简体   繁体   中英

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:

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? 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 ):

7.5.3.2 Better function member

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. 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 .

(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. Also, this question is the same as what you are asking OVerload with optional parameters which links to the following MSDN article 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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