简体   繁体   English

参数:(必需,可选)vs(必需,必需,可选)

[英]Parameters: (required, optional) vs (required, required, optional)

I have defined the following method: 我已经定义了以下方法:

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

The code compiled with no problem, so I wrote the code to execute it (from a diffferent file): 编译的代码没有问题,所以我编写了代码来执行它(来自不同的文件):

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

But it seemed like for some reason it just did nothing. 但似乎由于某种原因它什么也没做。
After a few minutes of struggling to understand the problem, I finally found it. 经过几分钟的努力才能理解这个问题,我终于找到了它。 Somewhere in the same class, there was already a Write function defined like this: 在同一个类的某个地方,已经有一个像这样定义的Write函数:

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

This really confused me, as it did compile fine, and of course, it makes sense as one method has 3 parameter signature and the other one has 2, but isn't this very ambiguous and/or error prone? 这真的让我很困惑,因为它编译得很好,当然,它有意义,因为一个方法有3个参数签名而另一个有2个,但这不是很模糊和/或容易出错吗? For me it seems like none of the methods are the "logical" one to choose. 对我来说,似乎没有一种方法是“合乎逻辑的”选择方法。 Why is the 2nd one chosen over the other? 为什么选择第二个而不是另一个?

Yes, method resolution can be tricky, so always remember that when you write multiple overloads. 是的,方法解析可能很棘手,因此在编写多个重载时请务必记住。 They should not be ambiguous for you as they are now. 他们现在不应该对你不明确。 The compiler just picked the shortest match, which is exactly as it should, because it is documented to do that. 编译器刚刚选择了最短的匹配,这完全是应该的,因为它记录了这样做。

There are two things you can do: 你可以做两件事:

  • Rename one of the methods. 重命名其中一种方法。 This will make method resolution a piece of cake, and absolutely clear, for you and the compiler. 对于您和编译器而言,这将使方法解决变得轻而易举,并且绝对清晰。
  • Make the last parameter required for both. 制作两者所需的最后一个参数。 This will make the method resolution very clear again: on two vs. three parameters. 这将使方法分辨率再次非常清晰:在两个对三个参数上。

It's specified (in the overload resolution, section 7.5.3 of the C# specification ): 它是指定的(在重载决议中, C#规范的第7.5.3节):

7.5.3.2 Better function member 7.5.3.2更好的功能成员

For the purposes of determining the better function member, a stripped-down argument list A is constructed containing just the argument expressions themselves in the order they appear in the original argument list. 为了确定更好的函数成员,构造一个精简的参数列表A,它按照它们在原始参数列表中出现的顺序仅包含参数表达式本身。 Parameter lists for each of the candidate function members are constructed in the following way: 每个候选函数成员的参数列表按以下方式构造:

• The expanded form is used if the function member was applicable only in the expanded form. •如果函数成员仅适用于展开的表单,则使用展开的表单。

Optional parameters with no corresponding arguments are removed from the parameter list 从参数列表中删除没有相应参数的可选参数

• The parameters are reordered so that they occur at the same position as the corresponding argument in the argument list. •重新排序参数,使它们出现在与参数列表中相应参数相同的位置。

(...) (......)

• Otherwise if all parameters of M P have a corresponding argument whereas default arguments need to be substituted for at least one optional parameter in M Q then M P is better than M Q . •否则,如果M P的所有参数都具有相应的参数,而默认参数需要替换M Q中的至少一个可选参数,则M P优于M Q.

(etc.) (等等。)

So in your case, optional parameters with an argument are taken into account on the overload resolution, so the second one (with the optional parameter), matches more specifically your call (with two arguments) than the one you expected (which has three), so it's considered "better" 所以在你的情况下, 带有参数的可选参数会在重载决策中被考虑在内,所以第二个(带有可选参数),更具体地匹配你的调用(有两个参数)而不是你期望的那个(有三个) ,所以它被认为是“更好”

In the C# Spec (depending on version this might change) section 1.6.6.5 deals with Method Overloading. 在C#规范中(取决于可能更改的版本),第1.6.6.5节处理方法重载。 Also, this question is the same as what you are asking OVerload with optional parameters which links to the following MSDN article MSDN 此外,这个问题与您使用可选参数询问OVerload的问题相同,该参数链接到以下MSDN文章MSDN

Which contains the relevant section 其中包含相关部分

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. 这是对具有较少参数的候选者的重载分辨率的一般偏好的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM