Frage

Ich habe zwei Klassen:

public class MyBase
{
    public virtual void DoMe()
    {

    }
}

public class MyDerived:MyBase
{
    public override void DoMe()
    {
        throw  new NotImplementedException();
    }
}

Und ich habe den folgenden Code MyDerived zu instanziiert:

        MyDerived myDerived=new MyDerived();

Die Sache ist, wie DoMe der Basisklasse nennen? Wenn ich myDerived.DoMe () verwenden, dann ist der abgeleitete Methode Wil genannt werden, zu einer Ausnahme führt. Ich habe versucht, MyDerived zu MyBase zu werfen, aber es ist immer noch die abgeleitete Version der Methode, die aufgerufen wird.

Edit:. Wie im folgenden Kommentar erwähnt, kann ich nicht eitehr MyDerived oder MyBase ändern, weil sie nicht mein Code sind

War es hilfreich?

Lösung

Es gibt eine Lösung, aber es ist hässlich: Verwendung Reflexion die Basisklasse Methode zu bekommen, und dann die IL emittieren notwendig, es zu nennen. Schauen Sie sich diesem Blog-Eintrag , die veranschaulicht, wie zu tun diese. Ich habe diesen Ansatz erfolgreich verwendet es die Basisklasse Implementierung einer Methode aufrufen, wenn alles, was ich habe ein Verweis auf eine abgeleitete Klasse, die diese Methode überschreibt.

Andere Tipps

Sie können die Basisklassen-Version nicht nennen.

Wenn die Methode auf der abgeleiteten Klasse nicht funktioniert, dann ist es eher unwahrscheinlich, dass die Basisversion des Verfahrens wird funktionieren, wenn sie auf einer Instanz der abgeleiteten Klasse aufgerufen. Das ist nur Ärger bringen. Die Klasse wurde nicht entwickelt, so zu arbeiten, und was Sie wahrscheinlich versuchen, zu tun, wird nur in anderen Teilen der Klasse verursachen unvorhersehbar verhalten.

Warum wollen Sie auf das Objekt diese Methode aufrufen müssen, wenn das Objekt, das Sie sagt geradezu, dass es nicht funktionieren wird?

Es scheint mir, dass diese Klassen einige Konstruktionsfehler haben, und wenn Sie nicht erlaubt sind, die Klassen zu ändern, vielleicht sind Sie stattdessen zu einer gut gestalteten Bibliothek ändern erlaubt.

Um MyBase.DoMe () von einer externen Klasse aufrufe müssen Sie entweder eine Instanz von MyBase oder eine abgeleitete Instanz, die Domen nicht außer Kraft setzen (). Verfahren als virtuelle erklärt werden auf der tatsächlichen Laufzeittyp des Objekts aufgerufen werden, nicht die Art des Objekts, weshalb auf MyBase Gießen ändert sich nicht, welche Methode aufgerufen wird. Wenn jedoch das Verfahren nicht in MyBase als virtuelle erklärt wurde und MyDerived noch DoMe () implementiert, es wäre „versteckt“ die MyBase Implementierung. Wenn daher die Referenz MyDerived war es nennen würde MyDerived.DoMe (), aber in diesem Fall Gießen MyBase myBase = (MyBase) MyDerived und dann myBase.DoMe () aufrufen nennen würde MyBase.DoMe ().

Die abgeleitete Klasse muss nicht eine Implementierung des Verfahrens zur Verfügung zu stellen. Entfernen Sie es und die Umsetzung in der Basisklasse wird standardmäßig aufgerufen werden.

Wenn, im Gegensatz zu Ihrem Beispiel des Verfahren in der Basisklasse abstrakt ist, und Sie müssen eine Implementierung zur Verfügung stellen, aber es macht keinen Sinn, für die abgeleitete Klasse man dann zu schaffen, gibt es wahrscheinlich etwas falsch mit dem Design der Klassen.

public class MyDerived:MyBase{    
    public override void DoMe()    
    {        
        base.DoMe();
    }
}

EDIT:

Sie können die Basisklassen-Methode „von außen“ zugreifen, ohne die Subklassen-Methode durchlaufen. Ihre einzige Option ist Ihre Basisklasse direkt zu instanziiert und nennt es ist Methode.

MyBase mb = new MyBase();
mb.DoMe();

Ihre Einschränkungen gegeben, eine weitere Möglichkeit besteht:

herunterladen .NET Reflector. Decompile der vorhandene Code dann alle Änderungen, die Sie brauchen, machen Sie Ihre Situation zu unterstützen.

Natürlich die Rechtmäßigkeit dieser Überprüfung, bevor Sie fortfahren.

Diese Frage ist so alt, aber ich sehe nicht die folgende Option:

Sie können das ‚neue‘ Schlüsselwort überlappende Methoden spezifizieren. Dann würden Sie einfach auf die Klasse geworfen, dessen Methode, die Sie anrufen möchten.

    public class MyBase
    {
        public virtual void DoMe()
        {

        }
    }

    public class MyDerived:MyBase
    {
//note the use of 'new' and not 'override'
        public new void DoMe()
        {
            throw  new NotImplementedException();
        }
    }

Die Umsetzung

var myDerived = new MyDerived();
var derivedDoMe = myDerived.DoMe();
var baseDoMe = ((MyBase)myDerived).DoMe();
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top