我在使用C#进行编程时,想验证一下这篇文章中描述的C++行为是否也适用于C#:http://herbsutter.com/2013/05/22/gotw-5-solution-overriding-virtual-functions/ 然后我遇到了一个非常奇怪的问题:
public class BaseClass
{
public virtual void Foo(int i)
{
Console.WriteLine("Called Foo(int): " + i);
}
public void Foo(string i)
{
Console.WriteLine("Called Foo(string): " + i);
}
}
public class DerivedClass : BaseClass
{
public void Foo(double i)
{
Console.WriteLine("Called Foo(double): " + i);
}
}
public class OverriddenDerivedClass : BaseClass
{
public override void Foo(int i)
{
base.Foo(i);
}
public void Foo(double i)
{
Console.WriteLine("Called Foo(double): " + i);
}
}
class Program
{
static void Main(string[] args)
{
DerivedClass derived = new DerivedClass();
OverriddenDerivedClass overridedDerived = new OverriddenDerivedClass();
int i = 1;
double d = 2.0;
string s = "hi";
derived.Foo(i);
derived.Foo(d);
derived.Foo(s);
overridedDerived.Foo(i);
overridedDerived.Foo(d);
overridedDerived.Foo(s);
}
}
输出
Called Foo(double): 1
Called Foo(double): 2
Called Foo(string): hi
Called Foo(double): 1
Called Foo(double): 2
Called Foo(string): hi
显然,它偏好于将隐式转换的int转为double,而不是来自基类的更具体的Foo(int)。或者它隐藏了来自基类的Foo(int)?但这样的话:为什么Foo(string)没有被隐藏呢?感觉非常不一致......无论我是否覆盖Foo(int),结果都是相同的。有人能解释一下这里发生了什么吗?
(是的,我知道在派生类中重载基本方法是不好的实践——Liskov等——但我仍然不希望在OverriddenDerivedClass中调用Foo(int)!)