gpt4 book ai didi

c# - 对 C# 中的 "override"与 "new"感到困惑

转载 作者:IT王子 更新时间:2023-10-29 04:21:45 25 4
gpt4 key购买 nike

我有以下类(class):

class Base
{
public virtual void Print()
{
Console.WriteLine("Base");
}
}

class Der1 : Base
{
public new virtual void Print()
{
Console.WriteLine("Der1");
}
}

class Der2 : Der1
{
public override void Print()
{
Console.WriteLine("Der2");
}
}

这是我的主要方法:

Base b = new Der2();
Der1 d1 = new Der2();
Der2 d2 = new Der2();

b.Print();
d1.Print();
d2.Print();

输出为BaseDer2Der2

据我所知,Override 不会让之前的方法运行,即使指针指向它们。所以第一行也应该输出Der2。然而 Base 出来了。

这怎么可能?覆盖如何在那里不起作用?

最佳答案

您实际上从未重写 Print()Base 版本。您只是在 Der1 中使用单独的虚拟方法(同名)隐藏了它。

当您在方法签名上使用 new 关键字时 - 您是在告诉编译器这是一个恰好与您的基类之一的方法同名的方法 - 但是没有其他关系。您可以使这个新方法成为虚拟方法(就像您所做的那样),但这与覆盖基类方法不同。

Der2 中,当您覆盖 Print 时,您实际上覆盖了您在 Der1 中声明的"new"版本 - 而不是版本 基础。 Eric Lippert 有一个 excellent answer一个稍微不同的问题可能会帮助您推断 C# 语言中虚方法的处理方式。

在您的示例中,当您调用 Print 时,您在第一种情况下通过 Base 类型的引用调用它 - 因此隐藏(但未覆盖)版本Print 被调用。其他两个调用被分派(dispatch)到 Der1 的实现,因为在这种情况下,您实际上已经覆盖了该方法。

您可以在 MSDN documentation of new and override 中阅读更多相关信息.

您可能打算对 Der1 做的事情(就像您对 Der2 所做的那样)是使用 override 关键字:

class Base 
{
public virtual void Print()
{
Console.WriteLine("Base");
}
}

class Der1 : Base
{
// omitting 'new' and using override here will override Base
public override void Print()
{
Console.WriteLine("Der1");
}
}

关于c# - 对 C# 中的 "override"与 "new"感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2952887/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com