Es ist ziemlich rätselhaft herauszufinden, dass Generics Constraint nicht in den abgeleiteten Typ gegossen werden kann.
Sagen wir, ich habe den folgenden Code:
%Vor%Und raten Sie mal, diese Methode wird einen Kompilierungsfehler zurückgeben:
%Vor% Ich müsste zuerst baseClass
auf object
umwandeln, bevor ich es in DerivedClass
umsetzen kann, d. h.
Scheint mir ziemlich hässlich. Warum ist das so?
Zuerst sollten Sie eine Basistypvariable nicht in einen abgeleiteten Typ umwandeln. Es soll nicht funktionieren, nur umgekehrt.
Zweitens, warum es über object
funktioniert, liegt daran, dass Sie die Prüfungen für die Kompilierungszeit entfernen. Der Compiler kann prüfen, ob BaseType
nicht in DerivedType
umgewandelt werden kann. Aber wenn eine Variable object
ist, verlässt der Compiler es, vorausgesetzt, Sie wissen, was Sie tun. Selbst wenn es kompiliert wird, stürzt der Code während der Ausführung ab.
Die Antwort ist einfach: Der Compiler kann nicht wissen, dass T
in Ihrer FreeConversion
-Methode in DeriveClass
konvertiert werden kann.
Wie Sie bereits gesagt haben, besteht der billige Trick darin, zuerst zum Objekt und dann zum Typ zu springen, den Sie verwenden möchten. Hässlich, aber es funktioniert.
Abgesehen davon kann es sein, dass Sie gegen das Liskov-Substitutionsprinzip verstoßen, nichts, was Tieren schaden könnte, sondern Ihr Design in Richtung eines nicht zu erhaltenden Codes treiben kann.
Drittens ist ein netter Trick, Ihre Basisklasse den abgeleiteten Typ verfügbar zu machen, etwa so:
%Vor%Zunächst könnte der Typ T in Ihrer generischen Methode ein Vale-Typ oder Referenztyp sein. Und der Grund, warum Sie es über "Objekt" tun können, ist, dass Sie einfach Boxen-Unboxing tun, die für jeden Typ im System funktioniert.
Zweitens. Es wird eine schreckliche Idee sein, ein Basisklassenobjekt in eine abgeleitete Klasse umzuwandeln. Sie verletzen die Mechanismen von OOP.
Wenn Sie wirklich ein Objekt vom Typ zurückgeben möchten, das von der Basisklasse abgeleitet ist, ist hier eine Möglichkeit möglich - die Lösung ist der von Frank angebotenen Lösung ziemlich ähnlich.
%Vor%