为什么重载方法的优先级低于实例方法

我有基础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为什么它不是扩展方法?

为什么编译器没有选择更合适的方法?

因为它遵循语言规范的规则,其中在查找候选方法时忽略最初在基类中声明的任何候选方法(如果它们在派生类中被覆盖,则忽略),除非派生类没有任何适用的方法,此时搜索移动到基类等。

这是为了避免“脆弱的基类”问题 ,但我发现面对在派生类中重写的方法很难吞下。

C#4规范的相关位是7.4,以此结束:

对于类型参数和接口以外的类型中的成员查找,以及严格单inheritance的接口中的成员查找(inheritance链中的每个接口都具有正好零或一个直接基接口),查找规则的效果就是派生成员隐藏具有相同名称或签名的基本成员。

编辑:关于扩展方法……

为什么它不是扩展方法?

从规范的7.6.5.2节:

在其中一个表单的方法调用(第7.5.5.1节)中

 expr . identifier ( ) expr . identifier ( args ) expr . identifier < typeargs > ( ) expr . identifier < typeargs > ( args ) 

如果调用的正常处理找不到适用的方法,则尝试将该构造作为扩展方法调用进行处理

所以扩展方法基本上作为最后的手段使用。