我有这个代码:
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");
}
}
}
Run Code Online (Sandbox Code Playgroud)
它输出我:
Foo
Bar
Baz
Foo
Foo
Baz
Run Code Online (Sandbox Code Playgroud)
但是,我认为它应该是:
Foo
Bar
Baz
Foo
Baz
Baz
Run Code Online (Sandbox Code Playgroud)
因为Baz压倒了这个方法.这里发生了什么?我错过了什么吗?为什么fooBaz.Test()的输出是"Foo"而不是"Baz"?
Buz 是重写方法,这就是原因
Bar barBaz = new Baz();
barBaz.Test();
Run Code Online (Sandbox Code Playgroud)
将打印Baz.
但是Bar没有覆盖 - 它隐藏了基本方法Test并使新方法成为虚拟方法.然后Baz重写新方法Bar,而不是方法Foo.因此,如果您像这样引用它:Foo fooBaz = new Baz();那么它fooBaz被视为一个实例Foo,它不知道隐藏方法.
如果更改public new virtual void Test()为,则会生成您期望的输出public override void Test().
另请参阅以下主题: