【问题标题】:Resolving Ambiguities with Optional Parameters and Named Arguments使用可选参数和命名参数解决歧义
【发布时间】:2014-08-16 01:13:33
【问题描述】:

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

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# .net methods


【解决方案1】:

如果可能,调用不带默认参数即可应用的那个。

第一种情况

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

第一个方法被调用。

第二种情况:

Person(1, 46.5);

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

【讨论】:

    【解决方案2】:

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

    如需深入讨论,请参阅this article

    【讨论】:

      【解决方案3】:

      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);
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-10-25
        • 2017-08-26
        • 1970-01-01
        • 1970-01-01
        • 2011-02-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多