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

标签 c# .net overloading overriding

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

最佳答案

Why compiler doesn't select more suitible method?

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

这是 designed to avoid the "brittle base class" problem ,但面对在派生类中重写的方法,我发现这很难接受。

C# 4 规范的相关位是 7.4,结尾是这样的:

For member lookups in types other than type parameters and interfaces, and member lookups in interfaces that are strictly single-inheritance (each interface in the inheritance chain has exactly zero or one direct base interface), the effect of the lookup rules is simply that derived members hide base members with the same name or signature.

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

And why it is not extension method?

来自规范的第 7.6.5.2 节:

In a method invocation (§7.5.5.1) of one of the forms

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

if the normal processing of the invocation finds no applicable methods, an attempt is made to process the construct as an extension method invocation

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

关于c# - 为什么重载方法的优先级低于实例方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12110565/

相关文章:

c# - ...由于其保护级别 c#/asp.net 而无法访问

c# - MVC 密码字段输入引发 "A potentially dangerous Request.Form value was detected from the client"

.net - 关于学习哪些.NET ORM的一些建议

c# - 错误 "An attempt was made to access a socket in a way forbidden by its access permissions"

c++ - 使用 +(一元加)解决 lambda 的函数指针和 std::function 上的不明确重载

c# - 从模板生成多个输出文件

c# - 为什么 UserControl 不可能从 UserControl 以外的东西继承

.net - 如何在与 Xamarin Android 兼容的 PCL 中解码 JWT

c# - 奇怪情况下的 "You must add a reference to assembly"编译器错误

c++ - 什么时候更喜欢普通函数重载而不是模板(重载)?