Ich habe zwei Klassen: eine nicht generische Basisklasse
Node und eine generische abgeleitete Klasse
Node. Die Knoten bilden eine verkettete Liste, wobei jeder Knoten möglicherweise einen anderen Datentyp enthält.
Code: Select all
public class Node{
public Node NextNode{get; set;}
public static Node WithData(T data) => new Node(data);
}
public class Node: Node{
public T Data{get; set;}
public Node(T data) => Data = data;
}
Die Klassen können wie folgt verwendet werden:
Code: Select all
var node1 = Node.WithData(73); // the node contains an int
var node2 = Node.WithData("Good luck!"); // the node contains a string
node1.NextNode = node2; // chaining the nodes
Notify(node1.Data == 73)); // displays "true" (method Notify() omitted for brevity)
Notify(node1.NextNode.GetType()); // displays "Node`1[System.String]"
Notify(node1.NextNode.Data == "Good luck!");
//compile error: 'Node' does not contain a definition for 'Data'
Der Compiler beschwert sich, weil
NextNode zu
Node hochgestuft wird und nicht mehr vom Typ
Node, obwohl GetType() den richtigen generischen Typ anzeigt.
Ich kann das Problem lösen, indem ich zurück zu
Node (Typprüfungen entfallen für Kürze):
Code: Select all
Notify(((Node)node.NextNode).Data);
// verbose and the casting type is usually not known at compile time
Code: Select all
Notify(((dynamic)node.NextNode).Data); // slow, but works fine at runtime
Code: Select all
if(node.NextNode is Node stringNode) Notify(stringNode.Data);
else if(node.NextNode is Node intNode) Notify(intNode.Data);
// else if... etc.
// bad for maintenance, verbose, especially with many data types
Meine Fragen sind:[/b]
- Gibt es eine geeignetere Möglichkeit, Node auf Node herunterzuwandeln (vorzugsweise zur Laufzeit)?
< li>Gibt es einen besseren Ansatz oder ein besseres Design der beiden Klassen, um das zu vermeiden oder zu automatisieren? niedergeschlagen?
Ich habe zwei Klassen: eine nicht generische Basisklasse [b]Node[/b] und eine generische abgeleitete Klasse [b]Node[/b]. Die Knoten bilden eine verkettete Liste, wobei jeder Knoten möglicherweise einen anderen Datentyp enthält.
[code] public class Node{
public Node NextNode{get; set;}
public static Node WithData(T data) => new Node(data);
}
public class Node: Node{
public T Data{get; set;}
public Node(T data) => Data = data;
}
[/code]
Die Klassen können wie folgt verwendet werden:
[code] var node1 = Node.WithData(73); // the node contains an int
var node2 = Node.WithData("Good luck!"); // the node contains a string
node1.NextNode = node2; // chaining the nodes
Notify(node1.Data == 73)); // displays "true" (method Notify() omitted for brevity)
Notify(node1.NextNode.GetType()); // displays "Node`1[System.String]"
Notify(node1.NextNode.Data == "Good luck!");
//compile error: 'Node' does not contain a definition for 'Data'
[/code]
Der Compiler beschwert sich, weil [b]NextNode[/b] zu [b]Node[/b] hochgestuft wird und nicht mehr vom Typ [b]Node, obwohl GetType()[/b] den richtigen generischen Typ anzeigt.
Ich kann das Problem lösen, indem ich zurück zu [b]Node (Typprüfungen entfallen für Kürze):
[code] Notify(((Node)node.NextNode).Data);
// verbose and the casting type is usually not known at compile time
[/code]
[code] Notify(((dynamic)node.NextNode).Data); // slow, but works fine at runtime
[/code]
[code] if(node.NextNode is Node stringNode) Notify(stringNode.Data);
else if(node.NextNode is Node intNode) Notify(intNode.Data);
// else if... etc.
// bad for maintenance, verbose, especially with many data types
[/code]
Meine Fragen sind:[/b]
[list]
[*] Gibt es eine geeignetere Möglichkeit, [b]Node[/b] auf [b]Node[/b] herunterzuwandeln (vorzugsweise zur Laufzeit)?
< li>Gibt es einen besseren Ansatz oder ein besseres Design der beiden Klassen, um das zu vermeiden oder zu automatisieren? niedergeschlagen?
[/list]