2010-05-20 3 views
6

In der C# -Dokumentation stoßen Sie häufig auf ein Element, in dem die Beschreibung etwas wie folgt lautet: "Achten Sie darauf, die Basismethode aufzurufen, wenn Sie diese überschreiben."Existiert dieses Schlüsselwort? Wenn eine überschreibende Methode das übergeordnete Element aufrufen muss

Gibt es eine Möglichkeit, um zur Kompilierzeit sicherzustellen, dass man tatsächlich die Basisfunktion aufgerufen hat?

Hier ist ein Beispiel: Implementing a Dispose Method

Von den ersten Zeilen:

einer Dispose-Methode des Typs sollte alle Ressourcen freigeben, die es besitzt. Es sollte auch alle Ressourcen freigeben, die seinen Basistypen gehören, indem seine Dispose-Methode Dispose-Methode aufgerufen wird.

EDIT

Ich war Surfen und ich auf diesen Artikel kam, die eher relevant zu sein scheint. Es ist eher ein kleiner als ein Fehler, d. es hat gültige Verwendungen (wie jene erwähnt):

Call Super

+0

Können Sie ein Beispiel für ein solches Mitglied geben? Meinst du ein Mitglied in .NET Framework? – brickner

Antwort

8

Sie es nicht durchsetzen können, aber man kann es wie base.Foo(bar) über einen Aufruf tun. base können Sie auf Mitglieder der Klasse zugreifen, von der Sie erben.

Sie können dieses Verhalten mithilfe von template method pattern erzwingen. Zum Beispiel stellen Sie sich diesen Code hatte:

abstract class Animal 
{ 
    public virtual void Speak() 
    { 
     Console.WriteLine("I'm an animal."); 
    } 
} 

class Dog : Animal 
{ 
    public override void Speak() 
    { 
     base.Speak(); 
     Console.WriteLine("I'm a dog."); 
    } 
} 

Das Problem hier ist, dass jede Klasse von Animal Bedürfnisse vererben base.Speak(); nennen das Basisverhalten sicherzustellen ausgeführt wird. Sie können dies automatisch erzwingen, indem Sie den folgenden (etwas andere) Ansatz:

abstract class Animal 
{ 
    public void Speak() 
    { 
     Console.WriteLine("I'm an animal."); 
     DoSpeak(); 
    } 

    protected abstract void DoSpeak(); 
} 

class Dog : Animal 
{ 
    protected override void DoSpeak() 
    { 
     Console.WriteLine("I'm a dog."); 
    } 
} 

In diesem Fall Kunden nur noch die polymorphe Speak Methode sehen, aber das Animal.Speak Verhalten garantiert auszuführen. Das Problem ist, dass wenn Sie weitere Vererbung haben (z. B. class Dachsund : Dog), Sie eine weitere abstrakte Methode erstellen müssen, wenn Sie sicherstellen möchten, dass Dog.Speak ausgeführt wird.

+0

Jon hat tatsächlich zuerst die Vorlagenmethode Musterlösung gepostet. Entschuldige, ich wollte nicht auf Zehenspitzen treten. –

+0

Kein Problem - Sie haben ein konkreteres Beispiel gegeben. Ich werde meine Antwort vergessen. –

+0

Danke, ich werde diese Antwort akzeptieren. Andere haben es auch erwähnt, aber dies ist eine gute Zusammenfassung, die die wichtigen Vorbehalte enthält – Carlos

5

Sie können es so nennen:

public override void MyFunction() 
{ 
    // do dome stuff 
    SomeStuff(); 

    // call the base implementation 
    base.MyFunction(); 
} 

Aber wenn Sie gefragt werden, ob es „geprüft“ bei der Kompilierung sein kann - nein.

Sie könnten wahrscheinlich ein Abhängigkeitsanalyse-Tool wie NDepend verwenden, um Regeln zu erstellen, um dies zu überprüfen, und die Regeln als Teil der Kompilierung ausführen lassen, aber ich denke nicht, dass Sie das Forecement vom Compiler ausführen können selbst.

0

Ein gängiges Muster für eine einzelne Vererbungsebene ist die Bereitstellung einer nicht virtuellen Vorlagenmethode mit einem virtuellen Erweiterungspunkt.

protected virtual void ExtensionPoint() { } 

public void TemplateMethod() { 
    ExtensionPoint(); 
    ThisWillAlwaysGetCalled(); 
} 

Wenn alle Anrufe an die Operation die Vorlage Methode aufrufen, dann wird jede Überschreibung der Erweiterungspunkt genannt werden, zusammen mit dem Code in der Template-Methode, die immer aufgerufen wird.

Verwandte Themen