简体   繁体   English

c#6 bug? 虚拟新方法奇怪的行为

[英]c# 6 bug? virtual new method strange behavior

I have this code: 我有这个代码:

using System;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Foo foo = new Foo();
            Bar bar = new Bar();
            Baz baz = new Baz();
            Foo fooBar = new Bar();
            Foo fooBaz = new Baz();
            Bar barBaz = new Baz();

            foo.Test();
            bar.Test();
            baz.Test();
            fooBar.Test();
            fooBaz.Test();
            barBaz.Test();

            Console.ReadLine();
        }
    }

    internal class Foo
    {
        public virtual void Test()
        {
            Console.WriteLine("Foo");
        }
    }

    internal class Bar : Foo
    {
        public new virtual void Test()
        {
            Console.WriteLine("Bar");
        }
    }

    internal class Baz : Bar
    {
        public override void Test()
        {
            Console.WriteLine("Baz");
        }
    }
}

it outputs me: 它输出我:

Foo
Bar
Baz
Foo
Foo
Baz

But, I thought it should be: 但是,我认为它应该是:

Foo
Bar
Baz
Foo
Baz
Baz

Because Baz is overriding the method. 因为Baz压倒了这个方法。 What is happening here? 这里发生了什么? Am I missing something? 我错过了什么吗? Why did the output for fooBaz.Test() is "Foo" instead of "Baz"? 为什么fooBaz.Test()的输出是“Foo”而不是“Baz”?

Buz is overriding the method, that's why Buz压倒了这个方法,这就是原因

Bar barBaz = new Baz();
barBaz.Test();

will print Baz . 将打印Baz

But Bar is not overriding - it is hiding the base method Test and makes the new method virtual. 但是Bar并没有覆盖 - 它隐藏了基本方法Test并使新方法成为虚拟方法。 Then Baz is overriding the new method from Bar , not the method from Foo . 然后Baz重写了Bar的新方法,而不是来自Foo的方法。 So if you reference it like this: Foo fooBaz = new Baz(); 所以如果你像这样引用它: Foo fooBaz = new Baz(); then fooBaz is treated like an instance of Foo , which has no idea of the hiding method. 然后fooBaz被视为Foo一个实例,它不知道隐藏方法。

The output that you're expecting would be generated if you changed public new virtual void Test() to public override void Test() . 如果您将public new virtual void Test()更改为public override void Test()则会生成您期望的输出。

See also these topics: 另请参阅以下主题:

When you use the new keyword on Bar.Test you're saying it has no relation to Foo.Test other than that it has the same name. 当你在Bar.Test上使用new关键字时,你说它与Foo.Test没有任何关系,除了它具有相同的名称。 Since Baz inherits from Bar, it overrides Bar.Test but leaves Foo.Test unmodified. 由于Baz继承自Bar,它会覆盖Bar.TestFoo.Test修改Foo.Test

When you call fooBaz.Test it looks up the unmodified Foo.Test method and prints "Foo". 当你调用fooBaz.Test它会查找未修改的Foo.Test方法并输出“Foo”。

When you call barBaz.Test it looks up the overriden Bar.Test method and prints "Baz". 当你调用barBaz.Test它会查找覆盖的Bar.Test方法并输出“Baz”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM