public enum EnumTest
{
EnumEntry
}
public class TestClass
{
public string FunctionMember(string s, EnumTest t = EnumTest.EnumEntry)
{
return "Normal";
}
public string FunctionMember<T>(T t)
{
return "Generic";
}
}
class Program
{
static void Main(string[] args)
{
TestClass t = new TestClass();
Console.WriteLine(t.FunctionMember("a"));
}
}
打印“Generic”。删除, EnumTest t = EnumTest.EnumEntry
会使其打印为“正常”。
然而标准似乎很清楚,从 14.4.2.2更好的功能成员应用的第一个鉴别器是:
我是否遗漏了某些内容或编译错误?
答案 0 :(得分:8)
你错过了什么。这就是以下内容:
您使用一个参数调用该方法。只有一种方法有一个参数,即通用参数。这就是所选择的那个。
只有找不到匹配的方法时,才会查看带有可选参数的其他方法。
<强>参考文献:强>
C# 4.0 Specification,21.4中的最后一段:
作为一个平局规则,一个函数成员,其中显式给出的所有参数都优于提供默认值的参数,而不是显式参数。
MSDN,标题为“重载决议”,最后一个要点:
如果两个候选人被判断为同样好,则优先选择没有可选参数的候选人,其中参数在呼叫中被省略。这是对具有较少参数的候选者的重载分辨率的一般偏好的结果。
The C# Language Specification,章节“7.5.3.2更好的功能成员”:
每个候选函数成员的参数列表按以下方式构造:
- 如果功能成员仅适用于展开的表单,则使用展开的表单。
- 从参数列表
中删除没有相应参数的可选参数
它继续这样:
给定一个参数列表A,其中包含一组参数表达式{E 1 ,E 2 ,...,E N }和两个适用的函数成员MP和MQ,参数类型为{P 1 ,P 2 ,...,P N }和{Q 1 ,Q 2 ,...,Q N } [...]
此时,带有可选参数的方法已经不在游戏中了。 N
为1,但该方法有两个参数。
答案 1 :(得分:3)
答案 2 :(得分:1)
使用方法参数的默认值,可以扩展重载决策。
从概念上讲,将运行v4之前的方法重载决策。如果找到匹配的匹配项将被使用。 (从概念上讲,因为这不是对它如何工作的描述,而是你如何能想到它)
在您的情况下,它只找到一个匹配作为您的通用方法
如果找不到匹配项,它将查找具有部分匹配的方法以及可以使用默认值完成匹配的方法。在你的情况下,你可以在这次运行中找到无结果方法,但是由于已经找到匹配,因此分辨率永远不会出现。
删除第二个参数时,最终会出现通用匹配和非通用匹配的情况。而且你在挑选非泛型的时候会采取这样的规则。
总而言之,一个好的经验法则是选择最具体的方法。
匹配的非泛型方法比泛型更具体,因为类型不能改变。 使用默认参数的方法不如参数计数与参数计数匹配的方法(数字是精确匹配) 如果两个方法可用,但是一个接受IFoo的参数而另一个接受Foo(实现IFoo),则在将Foo对象作为参数传递时将选择后者,因为它是完全匹配的Ie。更具体的