在基类中标记ToString虚拟,会发生什么?

时间:2011-02-09 18:37:41

标签: c# virtual override

考虑以下(LinqPad)示例。 X类中的ToString标记为虚拟。为什么这里的输出不等于“嗨,我是Y,嗨,我是X”,而是打印出类型名称?当然标记ToString virtual是错误的,因为它在Object中定义为虚拟,我只是想了解这里发生了什么。

void Main()
{
    Y y = new Y();
    Console.WriteLine(y);
}

// Define other methods and classes here

class X
{
  public virtual String ToString() 
  {
    return "Hi, I'm X";
  }
}

class Y : X
{
  public override String ToString() 
  {
    return "Hi, I'm Y, " + base.ToString();
  }
}

2 个答案:

答案 0 :(得分:15)

这会在名为X的{​​{1}}中创建一个隐藏ToString()虚拟方法。所以如果你有:

Object.ToString()

致电

Y y = new Y();
X x = y;
Object o = y;

Console.WriteLine(y.ToString()); // Shows "Hi, I'm Y, Hi, I'm X";
Console.WriteLine(x.ToString()); // Shows "Hi, I'm Y, Hi, I'm X";
Console.WriteLine(o.ToString()); // Calls object.ToString; shows just "Y"

相当于最后一行,这就是打印类型名称的原因。

基本上,您的Console.WriteLine(y); 方法应覆盖 X.ToString方法:

object.ToString()

答案 1 :(得分:8)

virtual String ToString()上使用class X,您“隐藏”object.ToString而不是覆盖它。

当您致电Console.WriteLine(y);时,会拨打object.ToString()。由于你没有覆盖它,你的方法永远不会被调用。

话虽如此,编译器会警告你:

  

警告1'X.ToString()'隐藏继承的成员'object.ToString()'。要使当前成员覆盖该实现,请添加override关键字。否则添加新关键字。