我有两个重载方法,一个带有可选参数。
void foo(string a) { }
void foo(string a, int b = 0) { }
现在我打电话给:
foo("abc");
有趣的是,调用了第一个重载。
为什么第二次重载的可选值设置为零?
老实说,我希望编译器带来错误,至少是一个警告,以避免无意中执行错误的方法。
这种行为的原因是什么?为什么C#团队以这种方式定义它?
答案 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#将它用于可选参数。添加警告/错误可能会为这些应用程序带来重大变化。
可能还有其他一些原因,但这首先是我想到的。