Wie die Rückkehr der Subtyp in der überschriebenen Methoden der Unterklasse in C#?
Habe ich eine Unterklasse mit einer über-geritten-Methode, die ich kenne immer wieder ein bestimmter Subtyp des Rückgabetyps der Deklaration in der Basisklasse. Wenn ich den code schreiben, der auf diese Weise, es wird nicht kompiliert. Da das wahrscheinlich nicht sinnvoll, lassen Sie mich ein code-Beispiel:
class BaseReturnType { }
class DerivedReturnType : BaseReturnType { }
abstract class BaseClass {
public abstract BaseReturnType PolymorphicMethod();
}
class DerivedClass : BaseClass {
//Compile Error: return type must be 'BaseReturnType' to match
//overridden member 'BaseClass.PolymorphicMethod()'
public override DerivedReturnType PolymorphicMethod() {
return new DerivedReturnType();
}
}
Gibt es eine Möglichkeit, dies in C#? Wenn nicht, was ist der beste Weg, etwas zu erreichen, ähnlich? Und warum ist es nicht erlaubt? Es scheint nicht, daß jede logische Inkonsistenz, da jedes Objekt zurückgegeben, die von der über-geritten-Methode noch is BaseReturnType
. Vielleicht gibt es etwas, was ich nicht hatte, als wenn. Oder vielleicht der Grund ist die technologische oder historische.
Ich habe den compiler-Fehler als Kommentar.
InformationsquelleAutor recursive | 2009-01-07
Du musst angemeldet sein, um einen Kommentar abzugeben.
Leider Nein, kovariante Rückgabetypen werden nicht unterstützt in C# für die Methode überschreiben. (Dito Parametertypen kontravariant.)
Wenn Sie implementieren eine Schnittstelle, die Sie implementieren können, explizit mit der "schwachen" version und auch eine öffentliche version mit dem stärkeren Vertrag. Für einfache überschreiben der übergeordneten Klasse, Sie haben diesen Luxus nicht, fürchte ich 🙁
(EDIT: Marc hat eine vernünftige Lösung - obwohl, es ist ziemlich hässlich, und Methode versteckt ist generell schlecht für die Lesbarkeit. Aber nichts für ungut, Marc 😉
Ich glauben das ist eigentlich eine CLR-Einschränkung, nicht nur eine Sprache, aber ich könnte falsch sein.
(Als eine Angelegenheit der Geschichte, Java (die Sprache) hatten die gleiche Einschränkung bis 1.5 - aber es gewann Kovarianz zur gleichen Zeit wie Generika.)
Siehe diesen Kommentar von Eric Lippert darüber, warum C# nicht unterstützt, es stackoverflow.com/questions/1319663/...
InformationsquelleAutor Jon Skeet
Könnten Sie die Klasse generisch, wenn das nicht stört:
InformationsquelleAutor Stormenet
Können Sie dies tun, wenn Sie einführen eine zusätzliche Methode zu überschreiben (da kann man nicht
override
undnew
eine Methode mit dem gleichen Namen in der gleichen type):Jetzt haben Sie eine
PolymorphicMethod
Methode auf jeder Ebene mit dem richtigen Typ.InformationsquelleAutor Marc Gravell
Generika sind nicht unbedingt der Weg zu gehen. Insbesondere geben(Abgeleitet) ist nicht als ein Typ(der Basis).
Fügen Sie zunächst eine neue Methode für die abgeleitete Klasse, die zurückkehren wird der Wert mit dem richtigen Typ. Zweitens, markieren Sie die übergeordnete Methode, die nicht-überschreibbare und haben es delegieren an Ihre neue Methode.
Das ist es. Du hast dein problem gelöst. Untergeordnete Klassen werden nicht in der Lage, re-expand die Art, weil Sie überschreiben muss Ihre neue Methode.
Entschuldige ich mich, falls der code nicht ganz richtig ist; ich bin gewohnt, VB.net.
InformationsquelleAutor Craig Gidney
sollte diese Arbeit
Ich weiß, das ist möglich, aber es erfordert, dass Sie cast (new DerivedClass()).PolymorphicMethod (), wenn Sie wollen, es zu benutzen als ein DerivedReturnType. Das kann sein, was ich am Ende dabei, aber ich weiß nicht wie Gießen, wenn ich es vermeiden kann.
er werfen kann, die returnval überall dort, wo Sie gebraucht wird, als Abgeleitet
verdammt, ich tippe zu langsam 😛
Ja, aber das ist schmerzhaft und macht eine überprüfung erforderlich, bei der Ausführung, wenn wir in der Lage sein sollten zu erklären, dass es gültig ist zur compile-Zeit.
InformationsquelleAutor anand
Ändern Sie Ihre Signatur der Methode von Abgeleiteten Klasse:
C# nicht unterstützt Variante Rückgabetypen. Sie können sich diesen Beitrag für ein Weg dies zu tun ist die Verwendung von Generika...http://srtsolutions.com/blogs/billwagner/archive/2005/06/17/covaraint-return-types-in-c.aspx
Hier ist ein Beispiel für die Verwendung von Generika in Ihrem Modell:
InformationsquelleAutor JoshBerke
Scheint es mir, dass Sie brauchen, um wieder eine Schnittstelle, nicht auf eine Basisklasse.
InformationsquelleAutor Greg Hurlman