扩展方法重载

本文关键字:重载 方法 扩展 | 更新日期: 2023-09-27 18:21:08

我有这个扩展方法

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,也是

扩展方法重载

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

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

我相信这里的相关规范是7.5.3.2:

7.5.3.2更好的功能成员

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

给定具有一组自变量表达式{E1,E2,…,EN}的自变量列表A和具有参数类型{P1,P2,…,PN}和{Q1,Q2,…,QN}的两个适用函数成员MP和MQ,如果

  • 对于每个自变量,从EX到QX的隐含转换并不比从EX到PX的隐含转换好,并且

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

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

根据MSDN:

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

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

好吧,在这种情况下:

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时,都会调用这个扩展方法,因为这只是一个整数的方法,而不是对象的方法。