使用可选参数和命名参数解决歧义

本文关键字:参数 解决 歧义 | 更新日期: 2023-09-27 18:10:10

我的项目有两个方法,定义如下:

void Person(int ID, double height = 0.0, string team = "Knights")
{
   //my codes
}
void Person(int ID, double height = 0.0, string team = "Knights", int age = 30)
{
   //my codes
}

这是我调用方法的地方:

Person(1, 2.5, "Dark Ghost"); //calls first method

当我构建项目时,我没有得到任何错误,但我很困惑为什么上面调用第一个方法?

:

Person(1, 46.5);   //compiler error. 

使用可选参数和命名参数解决歧义

c#规范在§7.5.3.2中说,关于选择更好的重载:

如果[方法A]的所有参数都有对应的实参,而默认实参需要替换[方法B]中的至少一个可选参数,则[方法A]优于[方法B]。

为所有参数指定值时:

Person(1, 2.5, "Dark Ghost");

上述规则使第一个方法成为更好的候选方法,它被选为正确的重载。

当你不这样做的时候:

Person(1, 46.5);

规则不适用,重载解析是不明确的。


你可能会说,为什么不选择参数最少的那个呢?一开始看起来很好,但是当您有这样的内容时就会产生问题:

void Foobar(int a, string b = "foobar")
{
}
void Foobar(int a, int b = 0, int c = 42)
{
}
...
Foobar(1);

在这种情况下,没有正当理由选择第一个而不是第二个。因此,您只能通过为所有参数提供一个值来正确解决这个问题。

如果可能,调用不需要默认参数的那个。

第一种情况

Person(1, 2.5, "Dark Ghost");

第一个方法被调用

第二种情况:

Person(1, 46.5);

它只会导致构建错误。该调用在以下方法或属性之间是不明确的:测试。Person(int, double, string)和Person(int, double, string, int)"。

TL:DR第一个方法(最具体的)将被调用,因为在这种情况下,不需要使用默认值绑定参数。