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

发布于 2024-10-16 09:24:02 字数 475 浏览 2 评论 0原文

请考虑以下 (LinqPad) 示例。类 X 中的 ToString 被标记为虚拟。为什么这里的输出不等于“Hi,I'm Y,Hi,I'm 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();
  }
}

Consider the following (LinqPad) example. ToString in class X is marked virtual. Why is the output here not equal to "Hi, I'm Y, Hi, I'm X" but instead the typename is printed? Of course marking ToString virtual is wrong, because it is defined in Object as virtual, I am just trying to understand what is happening here.

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();
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

愛放△進行李 2024-10-23 09:24:02

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

调用 just

Console.WriteLine(y);

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

基本上,您的 X.ToString 方法应该覆盖 object.ToString() 方法:

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

That's creating a new virtual method in X called ToString() which hides Object.ToString(). So if you have:

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"

Calling just

Console.WriteLine(y);

is equivalent to the final line, which is why the type name is printed.

Basically, your X.ToString method should override the object.ToString() method:

public override String ToString() 
{
    return "Hi, I'm X";
}
我的鱼塘能养鲲 2024-10-23 09:24:02

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

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

话虽这么说,编译器会警告你:

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

By using virtual String ToString() on class X, you're "hiding" object.ToString instead of overriding it.

When you call Console.WriteLine(y);, it calls object.ToString(). Since you didn't override this, your method never gets called.

That being said, the compiler will warn you:

Warning 1 'X.ToString()' hides inherited member 'object.ToString()'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文