Ich habe eine Situation, in der ich eine Klasse habe
%Vor%Nun kann ich eine Schnittstelle dafür erstellen
%Vor%Was sollten die Fragezeichen ersetzen? Jede Klasse sollte ihren eigenen Typ zurückgeben, nicht Foo.
Die folgenden Lösungen funktionieren, sehen aber nicht sauber aus. Ich verstehe nicht, warum ich dieselbe Klasse zweimal angeben muss, und es gibt nichts wie "das" für den aktuellen Typ
So benutze ich es später
%Vor%Sie fragen:
Die folgenden Lösungen funktionieren, sehen aber nicht sauber aus. Ich verstehe nicht, warum ich dieselbe Klasse zweimal angeben muss, und es gibt nichts wie "das" für den aktuellen Typ
Der Grund, warum Sie es zweimal angeben müssen, liegt daran, dass C # nicht über die Funktion verfügt, die Sie benötigen. Was Sie wollen, ist etwa so:
%Vor%Aus Sicht der Typsicherheit sollte dies funktionieren (es heißt Rückgabetyp-Kovarianz ). In der Tat unterstützen andere Programmiersprachen wie C ++ oder Java dies, siehe dieses Beispiel auf Wikipedia . Leider wird Rückgabetyp-Kovarianz von C # nicht unterstützt (nicht einmal C # 4.0, was die Kovarianz für Generika einführte), weshalb Sie die in den anderen Antworten dargestellte "Generika-Problemumgehung" verwenden müssen.
Kovariante Rückgabetypen sowie ein "This" -Typ sind vorgeschlagene Features für neue Versionen von C #:
Sie könnten einen generischen Typ hinzufügen und ihn mit dem Schnittstellentyp einschränken:
%Vor%Sie würden dies wie folgt implementieren:
%Vor%Update , wenn Sie sich nicht um den konkreten Rückgabetyp von Foo kümmern, können Sie Folgendes tun:
%Vor%Was ist implementiert wie:
%Vor%Dann in Ihrer generischen Klasse:
%Vor% GenericClass<Foo>.Rar();
wird eine konkrete Implementierung von Foo
sein.
Ich denke, dass die wirkliche Frage ist: Warum brauchen Sie den abgeleiteten Typ in der Schnittstelle? Interface ist genau deshalb - Abstraktion von den konkreten Klassen. Wenn es nur für die Bequemlichkeit ist, also müssen Sie nach dem Aufruf von Bar () nicht nach Foo umwandeln, können Sie die Schnittstelle explizit implementieren:
%Vor%Stellen Sie sich die Frage: Warum stellen Sie eine Schnittstelle vor, wenn Sie den konkreten Typ möchten?
Um dies zu erreichen, können Sie eine abstrakte Basisklasse plus explizite Member-Implementierung verwenden. Deklarieren Sie zunächst Ihre Schnittstelle wie folgt:
%Vor%Deklarieren Sie eine generische abstrakte Klasse, die IFoo explizit implementiert, und deklarieren Sie auch eine abstrakte Methode, die Bar () "überlädt", aber generisch:
%Vor%Definieren Sie nun Ihre konkreten Klassen wie folgt:
%Vor%Der Vorteil dieses Ansatzes besteht darin, dass Sie nicht-generische IFoo-Referenzen verwenden können, um konkrete Instanzen zu halten . Wenn Sie Ihre Schnittstelle generisch machen, können Sie diese beispielsweise nicht deklarieren:
%Vor%Tags und Links c# inheritance interface