【问题标题】:Parameters: (required, optional) vs (required, required, optional)参数:(必需,可选)vs(必需,必需,可选)
【发布时间】:2016-06-23 10:35:11
【问题描述】:

我定义了以下方法:

void Write(string fileContent, string fileName, string container = StorageBlobContainers.ProfilePictures)

代码编译没有问题,所以我写了代码来执行它(来自不同的文件):

string json = JsonConvert.SerializeXNode(node);
FileProcessor.Write(json, "productscontainer");

但由于某种原因,它似乎什么也没做。
经过几分钟的努力理解问题后,我终于找到了它。在同一个类的某个地方,已经有一个 Write 函数定义如下:

void Write(string filePath, string container = StorageBlobContainers.ProfilePictures)
{
  if (!File.Exists(filePath))
    return string.Empty;
  ...

这真的让我很困惑,因为它编译得很好,当然,这是有道理的,因为一种方法有 3 个参数签名,另一种有 2 个,但这不是很模棱两可和/或容易出错吗?对我来说,似乎没有一种方法是“合乎逻辑”的选择。为什么选择第二个而不是另一个?

【问题讨论】:

  • "为什么选择第二个而不是另一个?" - 因为这些是语言的规则。如果您愿意,我们可以从语言规范中剔除并指出导致这一点的具体原因,但这不太可能让您更进一步。
  • 第二种方法怎么不是一个合乎逻辑的选择?您正在调用具有 2 个字符串参数的方法,而选择的方法是具有 2 个字符串参数的方法。这是一个完美的契合。
  • 另外,请记住,可选参数是在版本 1 之后添加到语言中的,仅仅返回旧代码和添加默认值的行为不应该导致之前编译的代码无法编译或选择其他方法。

标签: c# overloading optional-parameters


【解决方案1】:

是的,方法解析可能很棘手,因此在编写多个重载时请始终记住这一点。他们不应该像现在这样对你模棱两可。编译器只是选择了最短的匹配,这正是它应该做的,因为它被记录在案。

你可以做两件事:

  • 重命名方法之一。这将使您和编译器的方法解析变得轻而易举,而且绝对清晰。
  • 设置两者都需要的最后一个参数。这将使方法解析再次变得非常清晰:两个与三个参数。

【讨论】:

    【解决方案2】:

    已指定(在重载决议中,C# specification 的第 7.5.3 节):

    7.5.3.2 更好的函数成员

    为了确定更好的函数成员,构造了一个精简的参数列表 A,其中仅包含参数表达式本身,按照它们在原始参数列表中出现的顺序排列。 每个候选函数成员的参数列表按以下方式构造:

    • 如果函数成员仅适用于扩展形式,则使用扩展形式。

    没有对应参数的可选参数从参数列表中删除

    • 参数被重新排序,以便它们出现在参数列表中与相应参数相同的位置。

    (...)

    • 否则,如果 MP 的所有参数都有对应的参数,而默认参数需要替换 MQ 中的至少一个可选参数,则 M P 优于 MQ

    (等等)

    因此,在您的情况下,可选参数 with 在重载决议中会考虑一个参数,因此第二个(带有可选参数)更具体地匹配您的调用(带有两个参数)比你预期的(三个),所以它被认为是“更好”

    【讨论】:

      【解决方案3】:

      在 C# 规范中(取决于版本,这可能会改变)第 1.6.6.5 节处理方法重载。此外,这个问题与您所问的问题相同 OVerload with optional parameters 链接到以下 MSDN 文章 MSDN

      其中包含相关部分

      如果两个候选者被判断为同样好,则优先考虑没有可选参数的候选者,在调用中省略了这些参数。这是由于参数较少的候选者普遍偏好重载解决方案的结果。

      【讨论】:

        猜你喜欢
        • 2017-06-14
        • 2017-01-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-05
        • 2019-07-25
        • 2014-08-02
        • 1970-01-01
        相关资源
        最近更新 更多