简体   繁体   中英

C# ToString inheritance

I have a problem (it's my fault, I just can't spot what I'm doing wrong) where "ToString" isn't calling the correct method...

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'm getting the "ToString" from "ClassB" and not "ClassA" what am I doing wrong?

You are not doing anything wrong -- this is how polymorphism virtual methods work. When you put ClassB into collection of ClassA references, it is still ClassB object. Invoking .ToString() will always find ClassB.ToString() if the object is indeed of ClassB.

You are overriding ToString in ClassB instead of hiding it from the original which will cause the overridden method to take precedence. What you could do is..

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

ToString is a virtual method, it doesn't matter what the type of your variable is, it matters what the type of the actual object is.

If the method wasn't virtual, a call would go to the method the compiler would know about, which would be the ClassA ToString method.

Virtual methods are implemented through a lookup table, bound to the object type. Since the object you end up with in variable "tempClassA" is really an object of type ClassB, the lookup table for ClassB is used, and thus the ToString method for that class is used.

You are getting the correct results. You add an instance of ClassB to your list; even though you treat it as a ClassA. Therefore, when you call the virtual ToString method, it will result in a call to ClassB's ToString; because that is the actual kind of object you are working with.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM