扩展方法重载
本文关键字:重载 方法 扩展 | 更新日期: 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();
时,是什么决定在这种情况下进行第二次扩展?int
是object
,也是
在这种情况下,第二次延期的决定是什么?
当编译器有多个有效方法可供选择时,它会使用一组重载解析规则来确定应该绑定到哪个方法。第二个扩展方法与调用签名完全匹配,因此会选择它。由于任何其他类型都可以直接转换为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的隐含转换好,并且
由于从int
到int
的"转换"比从int
到object
的转换"更好",因此选择了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时,都会调用这个扩展方法,因为这只是一个整数的方法,而不是对象的方法。