简体   繁体   English

C#ToString继承

[英]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... 我有一个问题(这是我的错,我只是无法发现我做错了什么)“ToString”没有调用正确的方法......

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? 我从“ClassB”而不是“ClassA”得到“ToString”我做错了什么?

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. 将ClassB放入ClassA引用的集合时,它仍然是ClassB对象。 Invoking .ToString() will always find ClassB.ToString() if the object is indeed of ClassB. 如果对象确实是ClassB,则调用.ToString()将始终找到ClassB.ToString()。

You are overriding ToString in ClassB instead of hiding it from the original which will cause the overridden method to take precedence. 您在ClassB中重写ToString而不是将其隐藏在原始文件中,这将导致重写的方法优先。 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. ToString是一个虚方法,它与变量的类型无关,重要的是实际对象的类型。

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. 如果该方法不是虚拟的,则调用将转到编译器将要知道的方法,该方法将是ClassA ToString方法。

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. 由于您在变量“tempClassA”中最终得到的对象实际上是ClassB类型的对象,因此使用ClassB的查找表,因此使用该类的ToString方法。

You are getting the correct results. 您获得了正确的结果。 You add an instance of ClassB to your list; 您将ClassB的实例添加到列表中; even though you treat it as a ClassA. 即使你把它当作ClassA。 Therefore, when you call the virtual ToString method, it will result in a call to ClassB's ToString; 因此,当您调用虚拟ToString方法时,它将导致调用ClassB的ToString; because that is the actual kind of object you are working with. 因为这是你正在使用的实际对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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