using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var a = new Derived();
int x = 123;
a.Foo(x);
}
}
public class Base
{
public virtual void Foo(int x)
{
Console.WriteLine("Base::Foo");
}
}
public class Derived : Base
{
public override void Foo(int x)
{
Console.WriteLine("Derived::Foo(int x)");
}
public void Foo(object o)
{
Console.WriteLine("Derived::Foo(object o)");
}
}
}
结果:“Derived :: Foo(object o)”
WHY ???
答案 0 :(得分:20)
当编译器试图找到候选方法签名以准备重载时,它首先查看最派生的类型,删除重写的方法仅查看该类中“新近声明的”签名。 / p>
如果找到适用的方法,则不会继续继承链继续查找其他签名。在这种情况下,这是违反直觉的(至少与我的直觉相反)。它旨在避免“脆弱的基类”问题,其中更改基类会以意想不到的方式影响其他代码 - 但是当派生类中的方法实际上被重写时,我看不到它的好处。 (无可否认地忽略这意味着看似无操作的方法覆盖方法只是为了调用基础实现并不像你期望的那样安全可移除。)
我有一个fairly long article在这个情况和其他极端情况的某些细节上超载 - 你可能会发现它很有用。有关更多详细信息,请参阅C#规范的7.5.3节。
底线:注意重载,特别是跨越继承边界。