I\'m wrestling with a weird, at least for me, method overloading resolution of .net. I\'ve written a small sample to reproduce the issue:
class Program
{
I agree with Jon Skeet's answer - refer to his post (above) on Jan 11 at 17:32. To expand further, please refer to C# language specification - page: 110
6.1.3 Implicit enumeration conversions An implicit enumeration conversion permits the decimal-integer-literal 0 to be converted to any enum-type and to any nullable-type whose underlying type is an enum-type. In the latter case the conversion is evaluated by converting to the underlying enum-type and wrapping the result (§4.1.10).
Still there is a problem:
adding the statement:
test.Execute(-0.0); //object overload: 0
while adding the following:
test.Execute(+0.0); //enum overload: 0
Jacques Colmenero Enterprise Architect colmeneroj@videotron.ca
Yes - the constant 0 is implicitly convertible to any enum type. The constant 1 is only explicitly convertible to the enum type. Both are implicitly convertible to object
(via boxing) but the conversion to the enum is preferred where it's available.
Note that this has nothing to do with what values the enum defines. The conversion for any non-zero value is explicit whether it matches a value in the enum or not. It's just a special case for the value 0, which makes some other code simpler (particularly when dealing with flags). I don't have the spec on hand to find the reference, I'm afraid.
Bonus strangeness: due to a bug in the MS compiler (never to be fixed - it would break backward compatibility) it's actually various zero constants, not just an integer. So Execute(0d)
and Execute(0m)
will convert a double and a decimal to the enum too. It doesn't work for every zero constant - it depends on the exact nature of the source code. It's all very odd - follow the link where Eric Lippert reveals all...
An Enum is just mapped to an int (by default). 0 does not map to your Enum so the overload that takes an object is used. 1 maps to your enum so the Enum overload is used.
You could do this:
Execute((object) 1);
to output
object overload: 1