When having a function Foo(object) and an overload Foo(Exception), calls to Foo(null) are evaluated by Foo(Exception). Why is this?
UPDATE: (so basically most but not all nulls gets resolved to Foo(Exception))
Exception e = new Exception();
e = null;
Foo bar = new开发者_JAVA技巧 Foo(e); //Evaulated by Foo(Exception) Foo bar = new Foo((object)e); //Evaluated by Foo(object)object o = null;
Foo bar = new Foo(o); //Evaluated by Foo(object) Foo bar = new Foo(null); //Evaulated by Foo(Exception) Foo bar = new Foo((object)null); //Evaulated by Foo(object)Thanks everyone.
Suppose you have a constructor that takes an Animal and a constructor that takes an Insect. You pass it a value of compile-time type Butterfly. Which one is called?
Insect. Both are valid, but the match from Butterfly to Insect is better than the match from Butterfly to Animal. Why? Because Insect is more specific than Animal. Every Insect is an Animal but some Animals are not Insects, so Insect must be more specific.
Same thing in your case. Exception is more specific than Object, so if you give an argument that matches both, Exception is chosen.
Make sense?
Duplicate of See How does the compiler choose which method to call when a parameter type is ambiguous?.
From the accepted answer:
It applies the "better conversion" rules (7.4.3.3 of the C# 3 spec) as part of overload resolution (section 7.4.3 in general).
Basically in this case there's a conversion from string to object, but not from object to string. Following the rules, that means the conversion from null to string is better than the one from null to object, so the overload with the string parameter is used.
The most relevant overload is selected - the one that is most derived and still fits the type passed in.
Since Exception
derives from Object
, it is chosen - a null
could stand for either, so the Exception
one is the one chosen.
I suggest reading the different articles by Eric Lippert.
The compiler resolves it at compile time by the type of reference of the parameter. For example:
Exception e = null;
Foo(e);
will be resolved to Foo(Exception e), in contrasts:
Exception e = null;
Foo((object)e);
will be resolved to Foo(object o). Note that the type of the instance is not taken into account.
精彩评论