generische Vererbung in C #? [Duplikat]

9

Ich kann

machen %Vor%

Wie würde ich die zweite machen? Wenn ich das nicht kann, wie kann ich etwas wie

tun %Vor%     
Community 14.04.2009, 17:59
quelle

7 Antworten

9

Dies ist nicht möglich, da sich die öffentliche Schnittstelle von MyGenericClass ändern würde, je nachdem, welcher Typ T ist.

Wenn Sie viele verschiedene Klassen haben, die alle die gleiche Schnittstelle bereitstellen, können Sie MyGenericClass deklarieren, um diese Schnittstelle verfügbar zu machen, und in der Implementierung aller Funktionen die Aufrufe an obj delegieren

    
Jason Coyne 14.04.2009 18:03
quelle
4

Sie könnten etwas wie

tun %Vor%

Bearbeiten: Jetzt verstehe ich die Frage

    
erikkallen 14.04.2009 18:16
quelle
4

Die spezifische Frage, warum können Sie das nicht tun:

%Vor%

Und Sie können dies tun:

%Vor%

Der Grund ist, dass die CLR in der Lage ist, eine einzige Version des Codes für MyGenericClass zu kompilieren, die für jeden für T angegebenen Referenztyp funktioniert.

Es kann dies für den zweiten Fall tun, weil es ruhig T durch object ersetzen und passende Umwandlungen einfügen kann, ungefähr äquivalent zu:

%Vor%

Aber für die Vererbungsversion funktioniert dieser Trick nicht.

Auch viele nützliche Einrichtungen wären unmöglich durch Schnittstellenbeschränkungen zu beschreiben. Wenn Sie von einem Typ erben, können Sie viel mehr tun, als nur Methoden aufzurufen - Sie können sie auch überschreiben. Betrachten Sie dieses hypothetische Beispiel:

%Vor%

Was ich dort machen möchte, ist etwas wie ein "Mix-in", bei dem MyGenericDerived Definitionen für virtuelle Funktionen in welcher Basis auch immer liefert. Aber wie weiß der Compiler, dass T eine Methode namens MyVirtual haben wird, die außer Kraft gesetzt werden kann? Ich müsste T einschränken. Wie würde ich das über Schnittstellen ausdrücken? Es ist unmöglich. Die Verwendung von Schnittstellen zur Beschreibung von Einschränkungen ist keine angemessene Lösung, wenn Sie die Vererbung von Typparametern zulassen. Das ist ein weiterer Grund, warum es heute nicht in der Sprache existiert.

    
Daniel Earwicker 14.04.2009 19:35
quelle
1

Das .NET-Typsystem lässt keine Typdeklarationen des Formulars zu, das Sie versuchen. Ein Grund, warum dies nicht erlaubt ist, sollte intuitiv sein: Wie würde MyGenericClass<T> handeln, wenn T eine versiegelte Klasse ist (z.B. System.String )?

Wenn Sie diese Funktionalität absolut benötigen (und Sie wissen, dass der Typ T , den Sie verwenden, nicht versiegelt ist), können Sie Proxies zur Laufzeit generieren, indem Sie die Klassen im Namensraum Reflection.Emit verwenden. Es ist auch möglich, diesen Effekt mit AOP-Tools wie PostSharp zu erreichen.

    
kvb 14.04.2009 19:24
quelle
0

Sie werden alle möglichen Ts benötigen, um eine Schnittstelle zu implementieren, so dass Sie wissen, dass obj.XYZ () sinnvoll ist, dann können Sie

machen %Vor%

Ich habe MyGenericClass auch dazu gebracht, Ixyz zu implementieren, da es offensichtlich die richtige Methode verfügbar macht, aber vielleicht sollte das am besten weggelassen werden, da es

erlaubt %Vor%

was wahrscheinlich nie eine gute Idee sein wird.

    
stevemegson 14.04.2009 18:18
quelle
0

Das ist so ziemlich Duck-Tipping, aber Sie könnten Reflexion verwenden. Wenn Sie die generische Klasse mit einem Verweis auf das obj erstellen, verwenden Sie reflection, um eine Methode mit der richtigen Signatur zu finden. Solange Sie einen Verweis auf die Methode speichern, ist die Leistung nicht zu schlecht.

%Vor%

Natürlich müssten Sie viel mehr für die Fehlerprüfung und dergleichen hinzufügen, aber das ist der Kern dessen, was Sie tun könnten. Vergessen Sie außerdem nicht, den System.Reflection-Namespace Ihrer using-Klausel hinzuzufügen.

    
Erich Mirabal 14.04.2009 18:30
quelle
0

Was ist damit?

%Vor%

Dies erreicht, was Sie tun möchten?

    
MRFerocius 14.04.2009 19:42
quelle

Tags und Links