先看这么一段代码:
public class Base
{
public virtual void DoWork( int a) { Console.WriteLine( "base dowork"); }
}
public class Derived : Base
{
public override void DoWork( int a) { Console.WriteLine( "Derived dowork"); }
public void DoWork(double a) { Console.WriteLine( "Derived dowork doubletype" ); }
}
下面这样调用它
int val = 5;
Derived d = new Derived();
d.DoWork(val);
请问,结果是什么,你猜猜?
我之前是学C++的,我的第一反应就是“Derived dowork”。这要是一段C++代码,那确实是这样,但这是C#。
结果是:Derived dowork doubletype
恩,为什么会这样呢?
C# 编译器将首先尝试使该调用与最初在 Derived 上声明的 DoWork 版本兼容。 重写方法不被视为是在类上进行声明的,而是在基类上声明的方法的新实现。 仅当 C# 编译器无法将方法调用与 Derived 上的原始方法匹配时,它才尝试将该调用与具有相同名称和兼容参数的重写方法匹配。
C# 语言经过专门设计,以便不同库中的基类与派生类之间的版本控制可以不断向前发展,同时保持向后兼容。 这具有多方面的意义。例如,这意味着在基类中引入与派生类中的某个成员具有相同名称的新成员在 C# 中是完全支持的,不会导致意外行为。 它还意味着类必须显式声明某方法是要重写一个继承方法,还是一个隐藏具有类似名称的继承方法的新方法。