为什么忽略基类中声明的签名?

class Base { public virtual void MethodA(int x) { Console.WriteLine ("In Base Class"); } } class Derived : Base { public override void MethodA(int x) { Console.WriteLine ("In derived INT)"); } public void MethodA(object o) { Console.WriteLine ("In derived OBJECT"); } } class Test { static void Main() { Derived d = new Derived(); int k = 20; d.MethodA(k); } } 

我得到的输出是“ In derived OBJECT ”。 这种奇怪行为的原因是什么? 经过一番研究,我发现原因是基类中声明的签名被忽略了 。 他们为什么被忽视?

这是设计上有充分理由的。 此设计有助于防止脆弱的基类问题。 C#旨在使编写“版本化”组件变得更容易和更安全,而这一规则是其中很重要的一部分。

这是一个非常常见的问题。 这是我们得到的最常见的“错误报告”之一; 也就是说,有人认为他们在编译器中发现了一个错误,实际上他们已经找到了一个function。

有关该function的说明及其设计原因,请参阅我关于此主题的文章:

http://blogs.msdn.com/b/ericlippert/archive/2007/09/04/future-breaking-changes-part-three.aspx

有关各种语言如何处理脆弱基类问题的更多文章,请参阅我关于该主题的文章存档:

http://blogs.msdn.com/b/ericlippert/archive/tags/brittle+base+classes/

VC#2008中的编译器在决定调用什么时检查虚拟函数之前的可用非虚函数。 由于Derived类具有可以调用的非虚方法(对象),因此编译器会调用它。

如果向Base添加虚拟MethodA(对象),则会调用Derived.MethodA(int),因为MethodA(object)和MethodA(int)都是虚拟的。

我对C#语言规范不太熟悉,不知道这是指定的行为,还是编译器中的错误。