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

时间:2010-04-20 10:53:02

标签: parameters c#-4.0 overloading optional-parameters

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

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

现在我打电话给:

 foo("abc");
有趣的是,调用了第一个重载。 为什么第二次重载的可选值设置为零?

老实说,我希望编译器带来错误,至少是一个警告,以避免无意中执行错误的方法。

这种行为的原因是什么?为什么C#团队以这种方式定义它?

3 个答案:

答案 0 :(得分:31)

来自MSDN

  

如果两个候选人被判断为同样好,则优先选择没有可选参数的候选人,其中参数在呼叫中被省略。这是对具有较少参数的候选者的重载分辨率的一般偏好的结果。

答案 1 :(得分:14)

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

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

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

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

  

否则,如果MP的所有参数都有   一个相应的论点,而   默认参数需要   替换至少一个可选的   MQ中的参数然后MP优于   MQ。

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

答案 2 :(得分:7)

想象一下是否相反。你有一个申请。它有一个方法:

void foo(string a)  { }   

一切都很好。现在,您想要使用可选参数添加一个重载:

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

轰!所有方法调用都转到新方法。无论何时你想要它。添加方法重载可能会导致整个应用程序的方法调用错误。

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

此外,在版本4.0中,C#中忽略了OptionalAttribute,但您可以使用它。有些人确实在C#代码中使用它来支持某些与其他语言(如Visual Basic)或COM互操作的互操作性方案。现在C#将它用于可选参数。添加警告/错误可能会为这些应用程序带来重大变化。

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