我有基础班A
public class A
{
public virtual void Method(A parameter)
{
Console.WriteLine(MethodBase.GetCurrentMethod());
}
public virtual void Method(B parameter)
{
Console.WriteLine(MethodBase.GetCurrentMethod());
}
}
遗传B
public class B : A
{
public virtual void Method(object parameter)
{
Console.WriteLine(MethodBase.GetCurrentMethod());
}
public override void Method(A parameter)
{
Console.WriteLine(MethodBase.GetCurrentMethod());
}
public override void Method(B parameter)
{
Console.WriteLine(MethodBase.GetCurrentMethod());
}
}
静态类S
用扩展方法
public static class S
{
public static void Method(this B instance, B parameter)
{
Console.WriteLine(MethodBase.GetCurrentMethod());
}
}
我们创建类型实例的示例B
并调用Method
对此,我们预计它将是public override void Method(B parameter)
实际结果是public virtual void Method(object parameter)
.
var b = new B();
b.Method(new B()); // B.Method (Object parameter) Why???
为什么编译器不选择更合适的方法???UPD为什么它不是扩展方法?
为什么编译器不选择更合适的方法?
因为它遵循语言规范的规则,任何候选方法最初宣布的在查找候选方法时,基类中的(如果它们在派生类中被重写)将被忽略,除非派生类没有任何适用的方法,此时搜索将向上移动到基类等。
This is 旨在避免“脆弱的基类”问题 http://blogs.msdn.com/b/ericlippert/archive/2007/09/04/future-breaking-changes-part-three.aspx,但我发现面对派生类中被重写的方法,这很难接受。
C# 4 规范的相关位是 7.4,其结尾如下:
对于类型参数和接口以外的类型中的成员查找,以及严格单继承的接口中的成员查找(继承链中的每个接口恰好有零个或一个直接基接口),查找规则的效果就是派生的成员隐藏具有相同名称或签名的基本成员。
编辑:关于扩展方法...
为什么它不是扩展方法?
来自规范第 7.6.5.2 节:
在其中一种形式的方法调用(第 7.5.5.1 节)中
expr . identifier ( )
expr . identifier ( args )
expr . identifier < typeargs > ( )
expr . identifier < typeargs > ( args )
如果调用的正常处理没有找到适用的方法,则会尝试将该构造作为扩展方法调用进行处理
所以一个扩展方法是only基本上用作最后的手段。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)