简体   繁体   中英

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. What is happening here? Am I missing something? Why did the output for fooBaz.Test() is "Foo" instead of "Baz"?

Buz is overriding the method, that's why

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

will print Baz .

But Bar is not overriding - it is hiding the base method Test and makes the new method virtual. Then Baz is overriding the new method from Bar , not the method from Foo . So if you reference it like this: Foo fooBaz = new Baz(); then fooBaz is treated like an instance of Foo , which has no idea of the hiding method.

The output that you're expecting would be generated if you changed public new virtual void Test() to 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. Since Baz inherits from Bar, it overrides Bar.Test but leaves Foo.Test unmodified.

When you call fooBaz.Test it looks up the unmodified Foo.Test method and prints "Foo".

When you call barBaz.Test it looks up the overriden Bar.Test method and prints "Baz".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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