扩展方法重载

时间:2015-11-09 13:43:47

标签: c# extension-methods

我有这种扩展方法

public static class Extensions
{
     public static void ConsoleWriteLine(this object Value)
     {
         Console.WriteLine(Value);
     }
}

对于整数值我有一点修改

public static void ConsoleWriteLine(this int Value)
{
    Console.WriteLine("Integer: " + Value);
}

我的问题是:当我写int x = 1; x.ConsoleWriteLine();时,是什么决定在这种情况下采取第二次延期? intobject以及

3 个答案:

答案 0 :(得分:5)

  

是什么决定在这种情况下采取第二次延期?

当编译器有多个有效方法可供选择时,它使用一组重载决策规则来确定它应该绑定到哪个方法。第二种扩展方法与调用签名完全匹配,因此选择它。由于任何其他类型直接可转换为object,因此将选择第一个扩展名。其他数字类型隐式可转换为int,但隐式转换并不比直接转换为父类“更好”。

我认为这里的相关规范是7.5.3.2:

  

7.5.3.2更好的职能成员

     

为了确定更好的函数成员,构造一个精简参数列表A,它按照它们在原始参数列表中出现的顺序仅包含参数表达式本身。   每个候选函数成员的参数列表按以下方式构造:

     

...

     

给定一个参数列表A,其中包含一组参数表达式{E1,E2,...,EN}和两个适用的函数成员MP和MQ,其参数类型为{P1,P2,...,PN}和{Q1 ,Q2,...,QN},MP被定义为比MQ更好的函数成员

     
      
  • 对于每个参数,从EX到QX的隐式转换并不比从EX到PX的隐式转换更好,并且
  •   

由于从intint的“转换”比从intobject的转换“更好”,因此选择了int重载。

请注意,这适用于所有重载,而非扩展方法(尽管有不同的规则可以打破扩展和非扩展方法之间的联系)。

答案 1 :(得分:2)

根据MSDN

  

当编译器遇到方法调用时,它首先查找a   匹配类型的实例方法。如果找不到匹配,则会   搜索为该类型定义的任何扩展方法,和   绑定到找到的第一个扩展方法

编译器从下到上进行搜索(即从子类到父类,直到它到达类层次结构的顶部),因此在这种情况下,最具体的方法将始终获胜。

答案 2 :(得分:0)

那么, 在这种情况下:

public static class Extensions
{
 public static void ConsoleWriteLine(this object Value)
 {
     Console.WriteLine(Value);
 }
}

您正在为对象编写扩展方法。 参见:

this object Value

在您的其他扩展方法中,您正在为整数编写扩展名。

public static void ConsoleWriteLine(this int Value)
{
   Console.WriteLine("Integer: " + Value);
}

由于

this int Value

因此,每次声明一个Integer时,都会调用此扩展方法,因为这只是一个整数的方法而不是一个对象。