2013-05-14 2 views
5

In C# enthält die Klasse A eine öffentliche Methode Foo(), die eine Verarbeitung durchführt und einen Wert zurückgibt. protected Methode Bar(), auch in Klasse A führt die gleiche Logik wie Foo(), gefolgt von einigen zusätzlichen Verarbeitung, und gibt dann einen Wert zurück.Aufruf der Basismethode anstelle der Überschreibung

Um doppelten Code zu vermeiden, ruft Bar()Foo() auf und verwendet den Rückgabewert als Zwischenwert.

class A 
{ 
    public virtual String Foo() 
    { 
    String computedValue; 
    // Compute the value. 
    return computedValue; 
    } 

    protected String Bar() 
    { 
    String computedValue; 
    String intermediateValue = Foo(); 
    /// More processing to create computedValue from intermediateValue. 
    return computedValue; 
    } 
} 

Klasse B erbt von A und überschreibt Foo(). Die Überschreibung ruft die Basisklassenimplementierung Bar() auf.

Dies geht (natürlich) in eine Endlosschleife, bis der Computer nicht mehr genügend Arbeitsspeicher hat und dann eine Stapelüberlauf-Ausnahme auslöst.

Die offensichtlichste Lösung ist, A mit einer privaten FooInternals Methode neu zu schreiben, die die Eingeweide von Foo enthält. Foo und Bar werden dann modifiziert, um die Ergebnisse dieser Methode zu verwenden.

Gibt es eine Möglichkeit, A's Bar() zu zwingen, A's Foo() statt der Überschreibung zu nennen?

(ich meine es mit ziemlicher Sicherheit Weg hier zu klug, dies vollständig gegen Polymorphismus geht Aber ich kann den Drang nicht wieder zu versuchen, weiter mein Wissen ein wenig drücken..)

Antwort

7

Gibt es eine Möglichkeit um zu erzwingen, dass A's Bar() anstelle von Override A's Foo() aufruft?

Nicht direkt. Die einfachste Refactoring wäre Foo zu ändern:

public virtual string Foo() 
{ 
    return FooImpl(); 
} 

private string FooImpl() 
{ 
    String computedValue; 
    // Compute the value. 
    return computedValue; 
} 

Dann Bar ändern FooImpl statt Foo zu nennen.

(Dies ist wahrscheinlich das, was Sie in Ihrem „naheliegendste Lösung“ Absatz gemeint -., Die ich auf der ersten Lesung verpasst, ich habe Angst)

dies im Grunde nur einer jener Bereiche, wo Vererbung problematisch ist . Wenn eine virtuelle Methode eine andere aufruft, muss dies dokumentiert werden, damit Unterklassen Probleme vermeiden können - obwohl es sich anfühlt, als ob ein Implementierungsdetail sein sollte. Das ist es, was mich dazu bringt, die Komposition der Vererbung vorzuziehen - wo beide natürlich sinnvolle Optionen sind.

+0

Danke, ich dachte, das wäre der beste/offensichtlichste Ansatz. Ich frage mich nur, ob ich eine Alternative verpasst haben könnte. – ThatBlairGuy

+1

@ ThatBlairGuy: Sorry, ich habe den Absatz in Ihrer Antwort verfehlt, der das beschreibt. Ups :) Aber nein, das ist alles, was du wirklich tun kannst. –

+0

Keine Sorge, danke für die Bestätigung, dass ich etwas nicht übersehen habe. – ThatBlairGuy