我有这种扩展方法
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
以及
答案 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的隐式转换更好,并且
由于从int
到int
的“转换”比从int
到object
的转换“更好”,因此选择了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时,都会调用此扩展方法,因为这只是一个整数的方法而不是一个对象。