我有两种重载方法,一种带有可选参数。
void foo(string a) { }
void foo(string a, int b = 0) { }
现在我打电话:
foo("abc");
有趣的是,调用了第一个重载。为什么不将可选值设置为零的第二个重载?
老实说,我本来希望编译器会带来一个错误,至少是一个警告,以避免无意执行错误的方法。
这种行为的原因是什么?为什么 C# 团队会这样定义它?
我有两种重载方法,一种带有可选参数。
void foo(string a) { }
void foo(string a, int b = 0) { }
现在我打电话:
foo("abc");
有趣的是,调用了第一个重载。为什么不将可选值设置为零的第二个重载?
老实说,我本来希望编译器会带来一个错误,至少是一个警告,以避免无意执行错误的方法。
这种行为的原因是什么?为什么 C# 团队会这样定义它?
来自MSDN:
如果两个候选者被判断为同样好,则优先考虑没有可选参数的候选者,在调用中省略了这些参数。这是对具有较少参数的候选者的重载解决方案的普遍偏好的结果。
不需要自动填充任何可选参数的重载优于需要自动填充的重载。但是,在自动填写一个参数和填写多个参数之间没有这样的偏好 - 例如,这将导致编译时错误:
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。
老实说,我认为在大多数情况下,这是大多数人所期望的行为。当您将基类方法引入混合时会变得很奇怪,但情况总是如此。
想象一下,如果它是相反的。你有一个应用程序。它有一个方法:
void foo(string a) { }
一切都很好。现在,您想添加一个带有可选参数的重载:
void foo(string a, int b = 0) { }
繁荣!所有方法调用都转到新方法。无论你想要与否。添加方法重载可能会导致整个应用程序中的错误方法调用。
从我的角度来看,在这种情况下,您将有更多机会破坏您(或其他人)的代码。
此外,直到 4.0 版,C# 中都忽略了OptionalAttribute,但您可以使用它。有些人确实在 C# 代码中使用它来支持与其他语言(例如 Visual Basic)或 COM 互操作的某些互操作性场景。现在 C# 将它用于可选参数。添加警告/错误可能会为这些应用程序引入重大更改。
可能还有其他一些原因,但这只是我首先想到的。