Wie rufe ich eine Unterklasse die Methode auf eine baseclass Objekt?
Ich bin mit einer Bibliothek, generiert eine Reihe von Klassen für mich.
Diese Klassen Erben alle von einer gemeinsamen Basisklasse aber, dass die Basisklasse nicht definiert ein paar Methoden, die für alle Unterklassen.
Beispiel:
SubClassA : BaseClass{
void Add(ItemA item) {...}
ItemA CreateNewItem() {...}
}
SubClassB: BaseClass{
void Add(ItemB item) {...}
ItemB CreateNewItem() {...}
}
Leider ist die Basisklasse nicht diese Methoden. Das wäre toll:
BaseClass{
//these aren't actually here, I'm just showing what's missing:
abstract void Add(ItemBaseClass item); //not present!
abstract ItemBaseClass CreateNewItem(); //not present!
}
Da gibt es eine gemeinsame Basisklasse für meinen A+B-Objekte und eine gemeinsame Basisklasse für die Item-Objekte, ich hatte gehofft, Sie zu nutzen-aus der wunderbaren Welt des Polymorphismus.
Leider, da die gängigen Methoden nicht tatsächlich in der base-Klasse, ich kann Sie nicht anrufen praktisch. z.B., das wäre perfekt:
BaseClass Obj;
Obj = GetWorkUnit(); //could be SubClassA or SubClassB
ItemBaseClass Item = Obj.CreateNewItem(); //Compile Fail: CreateNewItem() isn't in the base class
Item.DoSomething();
Obj.Add(Item); //Compile Fail: Add(...) isn't in the base class
Offensichtlich casting funktionieren würde, aber dann würd ich brauchen zu wissen, welche Art ich hatte, die würde negieren die Vorteile.
Wie kann ich die "Kraft" ein Aufruf dieser Methoden? Ich bin nicht besorgt über immer ein Objekt, das nicht implementieren die Methode, die ich bin versucht zu rufen. Ich kann eigentlich machen was ich will in VB--ich nicht bekommen, intellisense, aber der compiler ist zufrieden und es funktioniert:
CType(Obj, Object).Add(Item) //Note: I'm using C#--NOT VB
Gegen, ich habe keine Kontrolle über diese Klassen (was ich denke Regeln, partielle Klassen).
Sie haben die Kontrolle über die Unterklasse? Wenn Sie dies tun, gehen Sie mit Lucero Lösung.
Haren: C# nicht Option Strict an alle. Meine Lösung funktioniert, wenn Sie keine Kontrolle über die Klassen, Lucero ' s Lösung ist am besten, wenn Sie die Kontrolle über die Unterklassen.
InformationsquelleAutor Michael Haren | 2009-04-16
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie nicht an eine nicht-virtuelle Methode von einer abgeleiteten Klasse ohne Rückgriff auf Reflexion oder andere schmutzige tricks. Wenn Sie wollen, es zu tun, es ist einfach dann:
Warum ist Reflexion schmutzigen trick ? 🙂 Seine durchaus üblich heutzutage, und u können auch machen es zu führen equaly code ohne Reflexion
Es gilt als ein schmutziger trick, wenn Sie gotta verwenden Polymorphismus.
Haren: ich baute es zu VB für Sie. Die letzten parameter, werden die Parameter an die Methode übergeben, wenn Sie es brauchen.
Heh, ich dachte, es. Lassen Sie uns zurück konvertieren dann )
InformationsquelleAutor Mehrdad Afshari
Ich könnte etwas fehlen, aber warum ist das nicht und Erben von einem interface mit diesen Methoden?
Wenn Sie sind in der Steuerung des anlageprozesses für die Instanzen, die Sie möglicherweise bekommen, was Sie wollen, durch Erben von den Klassen, die Sie nicht geschrieben haben und fügen Sie dann die Schnittstelle (kein muss code geschrieben werden, der compiler ordnet die Schnittstelle zu den bestehenden nicht-virtuellen Methoden).
Vielleicht brauche ich, um genauer zu sein dann... 😉
Recht. Dies ist, was ich mit gestartet, aber ohne Kontrolle über die Klassen, ich kann es nicht.
Vielleicht hast du Recht. Deine Lösung funktioniert sogar, wenn Sie die Kontrolle über den Unterklassen. Ich bin mir nicht sicher, obwohl. Lassen Sie es hier, wenigstens zu helfen, die künftigen Besucher.
Also ich bräuchte Unterklasse jede der drei Klassen (Basis, a, b) und fügen Sie in einer Schnittstelle jeder Zeit, z.B. MissingBaseMethods{ Add(); CreateNewItem();}; fügen Sie ein wenig NotImplemented-code für die Basis, ignorieren A und B und dann zu instanziieren, diese neuen Klassen?
InformationsquelleAutor Lucero
Deklarieren Sie diese als virtuelle:
http://msdn.microsoft.com/en-us/library/9fkccyh4(VS.71).aspx
Die Basisklasse die Methoden müssen virtuell sein, zusammen mit dem "override" Schlüsselwort in der sub-Klasse Implementierungen. Siehe meine Antwort unten.
die Methoden sind nicht in der Basisklasse. Ich kommentierte weiter auf Ihre Antwort.
InformationsquelleAutor Stu
Andere Möglichkeit ist die Verwendung von proxy-Mechanismus, wie eine RealProxy (nicht sehr effizient in Bezug auf Leistung, obwohl), oder besser durch die Verwendung von dynamisch erstellten DynamicMethods so dass der Aufwand mit der spiegelung, ist nur einmal pro Typ zu unterstützen, während Sie so flexibel wie das Spiegelbild-Methode. Das zahlt sich aus großen, wenn Sie benötigen, rufen Sie die Methode mehrere Male, aber es erfordert etwas MSIL wissen.
InformationsquelleAutor Lucero
Problem #1: die Unterklassen sind nicht alles überschreiben
Problem #2: Ihre Unterklassen haben verschiedene Funktions-Signaturen als Ihre Basis-Klasse
Stellen Sie sicher, dass Ihre Signaturen korrekt sind, und wenn Sie überschreiben, markieren Sie eine virtuelle und nicht Abstrakt. Müssen Sie fügen Sie einen leeren Körper, um die Basis-Klasse virtuelle Funktionen, wenn Sie nicht wollen, etwas zu tun.
InformationsquelleAutor MStodd
Wenn Sie Visual Studio 2008 - erstellen Sie eine extension-Methode für die Basisklasse. Im inneren der Erweiterung Methode, die Sie würde tun, die-cast, und nennen Sie die Unterklasse die Methode. Diese Arbeit sollte für 2.0 Rahmen gezielter Projekte als gut, solange Sie kompilieren in VS 2008. Kreditaufnahme die anderen vorgeschlagenen Reflexions-code, können Sie das folgende tun...
Das ist eine nette Idee, aber der springende Punkt ist, zu beseitigen big switch-Blöcke wie dieser. Vielen Dank, aber.
wenn Sie nicht möchten, dass die switch-Blöcke - gehen mit der Reflexion route. Wenn die Leistung ein Anliegen, den switch-block könnte eine bessere route. Mit der Erweiterung Methode können Sie isolieren, Schalter bock in eine leicht aufrufbare Methode.
als 2. Gedanke, warum nicht eine Erweiterung Methode, die Reflexion?
Im Allgemeinen konnte ich nicht sagen, aber in diesem Fall ist es weil ich bin nicht mit VS2008. Nochmals vielen Dank.
InformationsquelleAutor Scott Ivey
Vergessen Sie die "override" Schlüsselwort in Ihrer sub-Klassen " - Methode, Definitionen. Wenn etwas als "Abstrakt" ist es per definition virtuelle, und damit in der sub-Klasse, die Sie benötigen, um setzen Sie die "override" - Schlüsselwort vor der Deklaration der Methode. So was funktionieren sollte ist unten:
Sollte dies genau so funktioniert, wie Sie wollen, in Ihrem Beispiel.
Ah, ich sehe. Also im Grunde Sie ' re suchen für-Schnittstelle-wie Verhalten auf Dinge, die nicht erklären, eine gemeinsame Schnittstelle. Ein bisschen schlampige design, wenn die Dinge, die mit gängigen Methoden nicht implementieren eine Schnittstelle. Schade.
InformationsquelleAutor Kevin Anderson