2009-03-30 14 views
3

Ich habe ein Problem (es ist meine Schuld, ich kann einfach nicht erkennen, was ich falsch mache), wo "ToString" nicht die richtige Methode aufrufen ...C# ToString Erbe

public class ClassA 
{ 
    public override ToString() 
    { 
     return "Hello, I'm class A."; 
    } 
} 

public class ClassB : ClassA 
{ 
    public override ToString() 
    { 
     return "Hello, I'm class B."; 
    } 
} 

ClassB myClassB = new ClassB(); 
List<ClassA> myClassAList = new List<ClassA>(); 

myClassAList.Add((ClassA) myClassB); 
ClassA tempClassA = myClassAList[0]; 
Console.WriteLine(tempClassA.ToString()); 

I bekomme den "ToString" von "ClassB" und nicht von "ClassA" was mache ich falsch?

+0

mehrere Tippfehler: "pulbic", "retutn", "pulbic" – abelenky

Antwort

4

Sie überschreiben ToString in ClassB, anstatt es vor dem Original zu verbergen, sodass die überschriebene Methode Vorrang hat. Was Sie tun könnten, ist ..

public class ClassA 
{ 
    public override string ToString() 
    { 
     return "Hello, I'm class A."; 
    } 
} 

public class ClassB : ClassA 
{ 
    public new string ToString() 
    { 
     return "Hello, I'm class B."; 
    } 
} 

... 

List<ClassA> theList = new List<ClassA> 
{ 
    (ClassA)new ClassB(), 
    (ClassA)new ClassB() 
}; 

ClassA a = theList[0]; 
Console.WriteLine(a.ToString()); 

// OR... 

Console.WriteLine(new ClassA().ToString()); // I'm Class A 
Console.WriteLine(new ClassB().ToString()); // I'm Class B 
Console.WriteLine(((ClassA)new ClassB()).ToString()); // I'm Class A 
+0

Dies ändert sich nichts. Sie können den Interface-Vertrag von 'ClassA' hier nicht unterbrechen. –

+1

Wenn Sie die ToString-Methode über neue und dann niedergeschlagenen ClassB zu KlasseA verbergen waren und rufen Sie toString() Sie würden KlasseA des überschriebenen ToString-Methode erhalten. Probieren Sie es aus Console.WriteLine (((ClassA) new ClassB()). ToString()); –

+0

Ich habe es versucht; Sie liegen falsch. –

0

ToString ist eine virtuelle Methode, ist es egal, was die Art Ihrer Variable ist, es zählt, was die Art des eigentlichen Objekts.

Wenn die Methode nicht virtuell war, wäre ein Aufruf der Methode gehen der Compiler kennen würde, die die KlasseA ToString-Methode wäre.

Virtuelle Methoden werden durch eine Lookup-Tabelle implementiert, auf den Objekttyp gebunden. Da das Objekt, mit dem Sie in der Variable "tempClassA" enden, wirklich ein Objekt vom Typ ClassB ist, wird die Nachschlagetabelle für ClassB verwendet, und daher wird die ToString-Methode für diese Klasse verwendet.

6

Du nichts falsch machen - das ist, wie Polymorphismus virtuelle Methoden arbeiten. Wenn Sie ClassB in Sammlung von ClassA-Verweisen einfügen, ist es noch ClassB-Objekt. Das Aufrufen von .ToString() wird ClassB.ToString() immer finden, wenn das Objekt tatsächlich von ClassB ist.

0

Sie erhalten die richtigen Ergebnisse. Sie fügen Ihrer Liste eine Instanz von ClassB hinzu. obwohl du es als ClassA behandelst. Wenn Sie die virtuelle ToString-Methode aufrufen, führt dies daher zu einem Aufruf von ClassB ToString; weil das die Art von Objekt ist, mit der Sie arbeiten.