C# 在基类中将ToString标记为virtual,会发生什么?

C# 在基类中将ToString标记为virtual,会发生什么?,c#,virtual,overriding,C#,Virtual,Overriding,考虑以下(LinqPad)示例。类X中的ToString标记为虚拟。为什么这里的输出不等于“嗨,我是Y,嗨,我是X”,而是打印字体名?当然,将字符串标记为virtual是错误的,因为它在Object中被定义为virtual,我只是想了解这里发生了什么 void Main() { Y y = new Y(); Console.WriteLine(y); } // Define other methods and classes here class X { public v

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

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();
  }
}
这在
X
中创建了一个名为
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()
方法:

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

通过在
类X
上使用
虚拟字符串ToString()
,您将“隐藏”对象.ToString,而不是覆盖它

当您调用
Console.WriteLine(y)时,它调用
对象.ToString()
。因为您没有重写这个,所以永远不会调用您的方法

话虽如此,编译器将警告您:

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


这是一个关于虚拟和非虚拟方法的演示:LinqPad中没有警告。。。但愿他们在那里。尝试最新的LINQPad测试版(www.LINQPad.net/beta.aspx)-它现在应该会显示警告。