iTa*_*ayb 25 c# virtual overriding new-operator
我有以下课程:
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");
    }
}
Run Code Online (Sandbox Code Playgroud)
这是我的主要方法:
Base b = new Der2();
Der1 d1 = new Der2();
Der2 d2 = new Der2();
b.Print();
d1.Print();
d2.Print();
Run Code Online (Sandbox Code Playgroud)
输出是Base,Der2,Der2.
据我所知,即使指针指向它们,Override也不会让以前的方法运行.所以第一行也应该输出Der2.然而Base出来了.
这怎么可能?覆盖如何在那里不起作用?
LBu*_*kin 28
你从来没有真正覆盖过的Base版本Print().您只使用单独的虚拟方法(名称相同)隐藏它Der1.
当您new在方法签名上使用关键字时 - 您告诉编译器这是一个碰巧与您的某个基类的方法同名的方法 - 但没有其他关系.您可以将此新方法设置为虚拟(如您所做),但这与覆盖基类方法不同.
在Der2当你重写Print你实际上是覆盖您在申报"新"版本Der1-而不是版本Base.Eric Lippert 对一个稍微不同的问题有一个很好的答案,可以帮助你推断如何用C#语言处理虚拟方法.
在您的示例中,当您调用时Print,您通过类型引用在第一种情况下调用它Base- 因此调用隐藏(但不覆盖)的版本Print.另外两个调用被调度到Der1实现,因为在这种情况下,你实际上已经覆盖了该方法.
您可以在新的和覆盖的MSDN文档中阅读有关此内容的更多信息.
您可能打算使用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"); 
    } 
} 
Run Code Online (Sandbox Code Playgroud)