为什么重载方法的优先级低于实例方法 [英] Why overloaded methods have lower priority than instance method

查看:119
本文介绍了为什么重载方法的优先级低于实例方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有基类 A

 大众A级
{
    公共虚拟void方法(A参数)
    {
        Console.WriteLine(MethodBase.GetCurrentMethod());
    }
    公共虚拟void方法(B参数)
    {
        Console.WriteLine(MethodBase.GetCurrentMethod());
    }
}
 

Inhereted B

 公共类B:
{
    公共虚拟void方法(对象参数)
    {
        Console.WriteLine(MethodBase.GetCurrentMethod());
    }

    公众覆盖无效的方法(A参数)
    {
        Console.WriteLine(MethodBase.GetCurrentMethod());
    }

    公众覆盖无效的方法(B参数)
    {
        Console.WriteLine(MethodBase.GetCurrentMethod());
    }
}
 

静态类取值与扩展方法

 公共静态S类
{
    公共静态无效的方法(这家B例如,B参数)
    {
        Console.WriteLine(MethodBase.GetCurrentMethod());
    }
}
 

例子中,我们创建类型实例 B 并调用方法就可以了,我们希望这将是公共覆盖无效的方法(B参数)实际结果是公共虚拟void方法(对象参数)

 变种B =新的B();
弘(新的B()); //弘(Object参数)为什么???
 

为什么编译器不会选择更多suitible方法??? UPD 为什么它不是扩展方法?

解决方案
  

为什么编译器不会选择更多suitible方法?

由于这是继语言规范,其中的任何候选方法的最初宣布的规则的基类(超过,如果他们在派生类中正在覆盖)发现一个候选方法时,忽略,除非派生类不具有任何适用的方法,搜索向上移动到基类在该点,等等。

这是<一个href="http://blogs.msdn.com/b/ericlippert/archive/2007/09/04/future-breaking-changes-part-three.aspx">designed避免脆基类问题,但我发现很难在方法的脸被吞在派生类中重写。

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

  

对于类型不是类型参数和接口,成员查找​​其他成员查找界面,令严格单一继承(继承链中的每个接口都只有零个或一个直接基接口),的查找规则的效果只是派生成员隐藏具有相同名称或签名的基成员。

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

  

和为什么它是不是扩展方法?

从规范的部分7.6.5.2:

  

在的一种形式的方法调用(第7.5.5.1节)

  EXPR。标识符()
EXPR。标识符(参数)
EXPR。标识符&LT; typeargs&GT; ()
EXPR。标识符&LT; typeargs&GT; (参数)
 

如果调用的正常处理没有发现适用的方法,试图处理该构建体作为扩展方法调用

因此​​,一个扩展方法的只有的使用作为最后的手段,基本上是这样。

I have base class A

public class A
{
    public virtual void Method(A parameter)
    {
        Console.WriteLine(MethodBase.GetCurrentMethod());
    }
    public virtual void Method(B parameter)
    {
        Console.WriteLine(MethodBase.GetCurrentMethod());
    }
}

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());
    }
}

Static class S with extension method

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

Example we create instance of type B and invoke Method on it, we expect that it will be public override void Method(B parameter) actual result is public virtual void Method(object parameter).

var b = new B();
b.Method(new B()); // B.Method (Object parameter) Why???

Why compiler doesn't select more suitible method??? UPD And why it is not extension method?

解决方案

Why compiler doesn't select more suitible method?

Because it's following the rules of the language specification, where any candidate methods originally declared in a base class (over if they're overridden in a derived class) are ignored when finding a candidate method, unless the derived class doesn't have any applicable methods, at which point the search moves up to the base class, etc.

This is designed to avoid the "brittle base class" problem, but I find that hard to swallow in the face of the method being overridden in the derived class.

The relevant bit of the C# 4 specification is 7.4, which ends with this:

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.

EDIT: About extension methods...

And why it is not extension method?

From section 7.6.5.2 of the spec:

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

So an extension method is only used as a last resort, basically.

这篇关于为什么重载方法的优先级低于实例方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆