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