使用可选参数冲突重载的方法

我有两个重载的方法,一个具有可选参数。

void foo(string a) { } void foo(string a, int b = 0) { } 

现在我打电话给:

  foo("abc"); 

有趣的是,第一个重载被调用。 为什么不把第二个重载与可选值设置为零?

说实话,我会期待编译器带来一个错误,至less是一个警告,以避免无意中执行错误的方法。

这是什么原因? 为什么C#团队这样定义呢?

来自MSDN :

如果两个候选人被判断为同样好,则优先select一个没有可选参数的候选人,这个参数在通话中被省略。 这是因为参数较less的候选人在重载分辨率方面普遍偏好的结果。

不需要任何可选参数自动填充的过载优先于那个。 但是,在自动填充一个参数和填写多个参数之间没有这样的偏好 – 例如,这会导致编译时错误:

 void Foo(int x, int y = 0, int z = 0) {} void Foo(int x, int y = 0) {} ... Foo(5); 

请注意,Foo(5,5)将被parsing为第二种方法,因为那样它不需要任何可选参数被自动填入。

来自C#4规范的第7.5.3.2节:

否则,如果MP的所有参数都有相应的参数,而默认参数需要replaceMQ中的至less一个可选参数,则MP比MQ好。

我认为在大多数情况下,这是大多数人所期望的行为,说实话。 当你将基类方法引入混合时,会变得很奇怪,但情况总是如此。

试想一下,如果情况正好相反。 你有一个应用程序。 它有一个方法:

 void foo(string a) { } 

Everyting工作正常。 现在,你想添加一个可选参数的重载:

 void foo(string a, int b = 0) { } 

繁荣! 所有的方法调用转到新的方法。 每当你想要或不需要。 添加一个方法重载可能导致整个应用程序调用错误的方法。

从我的angular度来看,在这种情况下,你会有更多的机会来破坏你的(或别人的)代码。

另外,C#中的OptionalAttribute在版本4.0之前被忽略,但是可以使用它。 有些人在C#代码中使用它来支持与其他语言(如Visual Basic)或COM互操作的某些互操作性场景。 现在C#使用它作为可选参数。 添加警告/错误可能会引发这些应用程序的重大更改。

可能还有一些其他的原因,但这正是我想到的。