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

时间:2022-03-21 10:56:22

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?

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

3 个解决方案

#1


29  

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.

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

#2


14  

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.

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

From section 7.5.3.2 of the C# 4 spec:

从C#4规范的7.5.3.2节:

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.

否则,如果MP的所有参数都具有相应的参数,而默认参数需要替换MQ中的至少一个可选参数,则MP优于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.

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

#3


7  

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.

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

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

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

#1


29  

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.

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

#2


14  

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.

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

From section 7.5.3.2 of the C# 4 spec:

从C#4规范的7.5.3.2节:

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.

否则,如果MP的所有参数都具有相应的参数,而默认参数需要替换MQ中的至少一个可选参数,则MP优于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.

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

#3


7  

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.

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

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

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