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

use*_*301 11 .net c# overriding overloading

我有基础课 A

public class A
{
    public virtual void Method(A parameter)
    {
        Console.WriteLine(MethodBase.GetCurrentMethod());
    }
    public virtual void Method(B parameter)
    {
        Console.WriteLine(MethodBase.GetCurrentMethod());
    }
}
Run Code Online (Sandbox Code Playgroud)

Inhereted 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());
    }
}
Run Code Online (Sandbox Code Playgroud)

S带扩展方法的静态类

public static class S
{
    public static void Method(this B instance, B parameter)
    {
        Console.WriteLine(MethodBase.GetCurrentMethod());
    }
}
Run Code Online (Sandbox Code Playgroud)

我们创建类型实例BMethod在其上调用的示例,我们期望它将是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???
Run Code Online (Sandbox Code Playgroud)

为什么编译器没有选择更合适的方法??? UPD为什么它不是扩展方法?

Jon*_*eet 10

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

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

这是为了避免"脆弱的基类"问题,但我发现在派生类中被覆盖的方法面对难以接受.

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

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

编辑:关于扩展方法......

为什么它不是扩展方法?

从规范的7.6.5.2节:

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

expr . identifier ( )
expr . identifier ( args )
expr . identifier < typeargs > ( )
expr . identifier < typeargs > ( args )
Run Code Online (Sandbox Code Playgroud)

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

因此,扩展方法基本上用作最后的手段.