static void F(string ham, object jam = null) { }
static void F(string spam, string ham, object jam = null) { }
...
F("meat product", null);
The developer of this odd code is apparently attempting to make optional parameters on both ends; the intention is that both spam and jam are optional, but ham is always required.
Which overload does the compiler pick, and why?
(I got the 开发者_StackOverflowquestion from blog of Eric Lippert)
The second overload is chosen. (Were you surprised?)
The reason why is straightforward. The overload resolution algorithm has two candidates and must pick which is the best one on the basis of the conversions from the arguments to the formal parameter types. Look at the first argument. Either it is converted to string, or to... string. Hmph. We can conclude nothing from this argument, so we ignore it.
Now consider the second argument. We either convert null to object, if we pick the first overload, or to string, if we pick the second overload. String is obviously more specific than object; every string is an object, but not every object is a string. We strive to pick the overload that is more specific, so we choose the second overload, and call
F("meat product", null, null);
http://blogs.msdn.com/b/ericlippert/archive/2011/02/10/optional-arguments-on-both-ends.aspx
精彩评论