Was passiert, wenn man von der CRTP-Konvention abweicht und schreibt...
public class Foo : TreeNode<Foo>
{
}
public class Bar : TreeNode<Foo> // parting from convention
{
}
...und rufen dann den obigen Code wie folgt auf:
var foo = new Foo();
var foobar = new Bar();
foobar.AddChild(foo);
Les AddChild
Aufruf löst eine InvalidCastException
unter Unable to cast object of type 'Bar' to type 'Foo'.
Was das CRTP-Idiom angeht, so ist es reine Konvention, dass der generische Typ mit dem deklarierenden Typ identisch sein muss. Die Sprache muss die anderen Fälle unterstützen, in denen die CRTP-Konvention nicht eingehalten wird. Eric Lippert hat einen großartigen Blogbeitrag zu diesem Thema geschrieben, den er in diesem anderen Blog verlinkt hat crtp über c# Antwort .
Das heißt, wenn Sie die Umsetzung folgendermaßen ändern...
public class TreeNode<T> where T : TreeNode<T>
{
public void AddChild(T a_node)
{
a_node.SetParent(this);
}
void SetParent(TreeNode<T> a_parent)
{
m_parent = a_parent;
}
TreeNode<T> m_parent;
}
...der obige Code, der zuvor die InvalidCastException
funktioniert jetzt. Die Änderung macht m_Parent
eine Art von TreeNode<T>
Herstellung this
entweder der Typ T
wie in der Foo
Klasse" oder einer Unterklasse von TreeNode<T>
im Bar
Klasse Fall seit Bar
erbt von TreeNode<Foo>
- In beiden Fällen können wir auf die Besetzung in SetParent
und vermeiden dadurch die Ausnahme der ungültigen Besetzung, da die Zuweisung in jedem Fall legal ist. Der Preis dafür ist, dass man nicht mehr in der Lage ist, frei zu verwenden T
an allen Orten, wie sie bisher verwendet wurden, was einen großen Teil des Wertes des CRTP einbüßt.
Ein Kollege/Freund von mir betrachtet sich selbst als Neuling in einer Sprache/Sprachfunktion, bis er ehrlich sagen kann, dass er sie "im Zorn" benutzt hat; das heißt, er kennt die Sprache gut genug, um frustriert zu sein, dass es entweder keine Möglichkeit gibt, das zu erreichen, was er braucht, oder dass es schmerzhaft ist, dies zu tun. Dies könnte sehr wohl einer dieser Fälle sein, da es hier Einschränkungen und Unterschiede gibt, die die Wahrheit widerspiegeln, dass Generika sind keine Vorlagen .