【问题标题】:Marking ToString virtual in base class, what happens?在基类中将 ToString 标记为虚拟,会发生什么?
【发布时间】:2023-03-03 06:27:23
【问题描述】:

考虑以下 (LinqPad) 示例。 X 类中的 ToString 被标记为虚拟。为什么这里的输出不等于“嗨,我是 Y,嗨,我是 X”,而是打印了类型名?当然标记 ToString 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();
  }
}

【问题讨论】:

标签: c# virtual overriding


【解决方案1】:

这是在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";
}

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

    • LinqPad 中没有警告...希望他们在那里 ;)。
    • 试用最新的 LINQPad 测试版 (www.linqpad.net/beta.aspx) - 现在应该会显示警告。
    猜你喜欢
    • 1970-01-01
    • 2016-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-03
    • 2013-04-02
    相关资源
    最近更新 更多