重载方法与可选参数发生冲突

发布于 2024-08-29 08:49:32 字数 298 浏览 3 评论 0原文

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

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

现在我调用:

 foo("abc");

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

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

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

I have two overloaded methods, one with an optional parameter.

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

now I call:

 foo("abc");

interestingly the first overload is called.
why not the second overload with optional value set to zero?

To be honest, I would have expect the compiler to bring an error, at least a warning to avoid unintentional execution of the wrong method.

What's the reason for this behaviour? Why did the C# team define it that way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

香橙ぽ 2024-09-05 08:49:32

来自 MSDN

如果两个候选者被认为同样优秀,则优先选择不具有可选参数且在调用中省略参数的候选者。这是重载决策中普遍偏好参数较少的候选者的结果。

From MSDN:

If two candidates are judged to be equally good, preference goes to a candidate that does not have optional parameters for which arguments were omitted in the call. This is a consequence of a general preference in overload resolution for candidates that have fewer parameters.

倾`听者〃 2024-09-05 08:49:32

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

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。

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

An overload which doesn't require any optional parameters to be filled in automatically is preferred to one which does. However, there's no such preference between filling in one argument automatically and filling in more than one - so for example, this will cause a compile-time error:

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

Note that Foo(5, 5) would be resolved to the second method, because then it doesn't require any optional parameters to be automatically filled in.

From section 7.5.3.2 of the C# 4 spec:

Otherwise if all parameters of MP have
a corresponding argument whereas
default arguments need to be
substituted for at least one optional
parameter in MQ then MP is better than
MQ.

I think in most cases this is the behaviour most people would expect, to be honest. It gets weird when you introduce base class methods into the mix, but that's always been the case.

幸福不弃 2024-09-05 08:49:32

试想一下,如果情况恰恰相反。你有一个申请。它有一个方法:

void foo(string a)  { }   

一切都很顺利。现在,您想添加一个带有可选参数的重载:

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

Boom!所有方法调用都会转到新方法。无论你想要与否,都可以。添加方法重载可能会导致整个应用程序调用错误的方法。

从我的角度来看,在这种情况下,您将有更多机会破坏您(或其他人)的代码。

此外,OptionalAttribute 在 C# 中被忽略,直到版本 4.0,但你可以使用它。有些人确实在 C# 代码中使用它来支持与其他语言(例如 Visual Basic)的某些互操作场景,或者用于 COM 互操作。现在 C# 使用它作为可选参数。添加警告/错误可能会给这些应用程序带来重大更改。

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

Just imagine if it were the opposite. You had an application. It had a method:

void foo(string a)  { }   

Everyting worked fine. Now, you want to add one more overload with an optional parameter:

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

Boom! All method calls go to the new method. Whenever you want it or not. Adding a method overload might cause wrong method calls all over the application.

From my perspective, in this case you'd have much more opporunities to break your (or someone else's) code.

Also, OptionalAttribute was ignored in C# until version 4.0, but you could use it. And some people did use it in C# code to support certain interoperability scenarios with other languages, such as Visual Basic, or for COM interop. Now C# uses it for optional parameters. Adding warnings/errors may introduce a breaking change for those applications.

There might be some other reasons, but this is just what comes to my mind first.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文