C#中方法重载的不同行为

Won*_*ing 14 c# inheritance overloading

我正在浏览C#Brainteasers(http://www.yoda.arachsys.com/csharp/teasers.html)并遇到一个问题:这段代码的输出应该是什么?

class Base
{
    public virtual void Foo(int x)
    {
        Console.WriteLine ("Base.Foo(int)");
    }
}

class Derived : Base
{
    public override void Foo(int x)
    {
        Console.WriteLine ("Derived.Foo(int)");
    }

    public void Foo(object o)
    {
        Console.WriteLine ("Derived.Foo(object)");
    }
}

class Test
{
    static void Main()
    {
        Derived d = new Derived();
        int i = 10;
        d.Foo(i);  // it prints ("Derived.Foo(object)"
    }
} 
Run Code Online (Sandbox Code Playgroud)

但是,如果我将代码更改为

class Derived 
{
    public void Foo(int x)
    {
        Console.WriteLine("Derived.Foo(int)");
    }

    public void Foo(object o)
    {
        Console.WriteLine("Derived.Foo(object)");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Derived d = new Derived();
        int i = 10;
        d.Foo(i); // prints  Derived.Foo(int)");

        Console.ReadKey();
    }
}
Run Code Online (Sandbox Code Playgroud)

我想为什么在继承而不是继承时输出会发生变化; 为什么方法重载在这两种情况下表现不同?

Jon*_*eet 19

正如我在答案页面中指定的那样:

打印Derived.Foo(object) - 在选择重载时,如果在派生类中声明了任何兼容方法,则忽略在基类中声明的所有签名 - 即使它们在同一派生类中被覆盖!

换句话说,编译器查看在最派生类中新近声明的方法(基于表达式的编译时类型),并查看是否有任何适用的方法.如果是,则使用"最佳"可用.如果不适用,则尝试基类,依此类推.重写的方法不计为在派生类中声明.

有关详细信息,请参阅C#3规范的7.4.3和7.5.5.1节.

至于为什么它被指定为那样 - 我不知道.对我来说,在派生类中声明的方法优先于在基类中声明的方法是有意义的,否则你会遇到"脆弱的基类"问题 - 在基类中添加一个方法可能会改变代码的含义.派生类.但是,如果派生类重写了基类中声明的方法,它就会清楚地意识到它,因此脆弱元素不适用.