2010-09-05 4 views
9
class Base 
{ 
    public virtual void MethodA(int x) 
    { 
     Console.WriteLine ("In Base Class"); 
    } 
} 

class Derived : Base 
{ 
    public override void MethodA(int x) 
    { 
     Console.WriteLine ("In derived INT)"); 
    } 

    public void MethodA(object o) 
    { 
     Console.WriteLine ("In derived OBJECT"); 
    } 
} 

class Test 
{ 
    static void Main() 
    { 
     Derived d = new Derived(); 
     int k = 20; 
     d.MethodA(k); 
    } 
} 

Der Ausgang, den ich dafür bekam, ist "In abgeleitetem OBJECT". Was ist der Grund für dieses seltsame Verhalten? Nach einigen Recherchen fand ich heraus, der Grund ist die Signaturen in der Basisklasse deklariert werden ignoriert. Warum werden sie ignoriert?Warum werden in der Basisklasse deklarierte Signaturen ignoriert?

+1

+1 auf die Frage, ich stimme dieses kontra-intuitives Verhalten. –

+0

Ich stimme zu, dass das Verhalten seltsam ist. Ich würde gerne wissen: Fragen Sie das, weil Sie das wirklich wollen oder weil Sie neugierig waren? Ich sehe keinen Grund, so etwas zu implementieren, aber ich würde gerne wissen, warum das passiert. –

+0

mögliches Duplikat von [Wie funktioniert das Ausblenden von Methoden in C#? (Teil zwei)] (http://stackoverflow.com/questions/710459/how-method-hiding-works-in-c-part-two) –

Antwort

6

Dies ist mit Absicht und aus einem guten Grund. Dieses Design verhindert das Problem der Sprödigkeit der Basisklasse. C# wurde entwickelt, um es einfacher und sicherer zu machen, "versionierte" Komponenten zu schreiben, und diese Regel ist ein großer Teil davon.

Dies ist eine sehr häufig gestellte Frage. Dies ist einer der häufigsten "falschen Fehlerberichte", die wir bekommen. Das heißt, jemand glaubt, dass sie einen Fehler im Compiler gefunden haben, obwohl sie tatsächlich ein Feature gefunden haben.

Eine Beschreibung der Funktion und warum es so ausgelegt ist, es ist, siehe meinen Artikel über das Thema:

http://blogs.msdn.com/b/ericlippert/archive/2007/09/04/future-breaking-changes-part-three.aspx

Weitere Artikel zum Thema, wie verschiedene Sprachen beschäftigen sich mit der Brittle Base Class Problem zu sehen, mein Archiv von Artikeln zu diesem Thema:

http://blogs.msdn.com/b/ericlippert/archive/tags/brittle+base+classes/

2

Der Compiler in VC# 2008 überprüft die verfügbaren nicht-virtuellen Funktionen vor virtuellen, bei der Entscheidung, was zu nennen ist. Da Ihre Derived-Klasse eine nicht virtuelle MethodeA (Objekt) hat, die aufgerufen werden kann, ruft der Compiler sie auf.

Wenn Sie Base eine virtuelle MethodA (Objekt) hinzufügen, wird Derived.MethodA (int) aufgerufen, da sowohl MethodA (Objekt) als auch MethodA (int) virtuelle Objekte sind.

Ich bin nicht vertraut genug mit der C# -Sprachspezifikation, um zu wissen, ob dies ein bestimmtes Verhalten oder ein Fehler im Compiler ist.

+0

Es ist tatsächlich in der ECMA-Spezifikation, non-virtual wird zuerst aufgerufen. Beachten Sie außerdem, dass die Methode, die aufgerufen wird, vom Compiler für nicht virtuelle Methoden und vom Laufzeittyp für virtuelle Methoden bestimmt wird. –

+0

Ich habe das überprüft, aber pass auf, dass Derived.MethodA (int) nur aufgerufen wird, wenn du das Schlüsselwort 'override' zu Derived.MethodA (object) hinzufügst (das war natürlich gemeint). Ohne es wird das optionale Schlüsselwort 'new' angenommen und Derived.MethodA (object) wird immer noch aufgerufen. – Gerard

Verwandte Themen