Reputation: 51
I recently noticed that C# compiler allows methods overloads like the following:
public static string foo(string a, bool x = false)
{
return "a";
}
public static string foo(string a)
{
return "b";
}
As far as I tested, it always returns "b" as long as the second param is not given, which makes sense. However, I think the compiler really should not allow this type of overloading. May I ask the reason why this feature is designed like this rather than giving an error by compiler?
Upvotes: 4
Views: 751
Reputation: 5207
I can't speak to why this is part of the design so much as simply explain why you see which overload is favored in your testing.
If you look at the reference documentation, you'll note the following three bullets to describe overload resolution:
I would assert that in your test, bullet #3 is most applicable to your observations - because you omit the second argument and either method is equally good, resolution favors your second method and you see "b" returned.
Upvotes: 1
Reputation: 36341
While questions like this are fundamentally impossible to answer, since it is impossible to guess the language designers intentions, I might make a guess.
Optional arguments are handled by transforming the code to inject the argument to the call site. So
public static void Test(int a = 42){...}
...
Test();
would be transformed to to
public static void Test(int a){...}
...
Test(42);
by the compiler. From this point on the regular overload resolution can run without conflicts. Why was it designed this way? I have no idea, but common reasons for non intuitive features is backward compatibility or language compatibility.
For this reason it is important to be very careful using optional arguments in public APIs. Since the user of the library will use the default value from the version of the API it was compiled against. Not the version it is running against.
Upvotes: 1