Why can I assign 0.0 to enumeration values, but not 1.0

Just out of curiosity: why can I assign 0.0 to a variable that is of an enumeration type, but not 1.0? Have a look at the following code:

public enum Foo
{
    Bar,
    Baz
}

class Program
{
    static void Main()
    {
        Foo value1 = 0.0;
        Foo value2 = 1.0;   // This line does not compile
        Foo value3 = 4.2;   // This line does not compile
    }
}

I thought that conversions between numerical types and enumeration values are only allowed via casts? That is I could write Foo value2 = (Foo) 1.0; so that line 2 in Main can compile. Why is there an exception for the value 0.0 in C#?

Jon Skeet
people
quotationmark

It's a bug that you can use 0.0. The compiler implicitly treats all constant expressions with a value of zero as just 0.

Now, it's correct for the compiler to allow an implicit conversion from a constant int expression of 0 to your enum as per section 6.1.3 of the C# 5 specification:

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

I've spoken with the C# team about this before: they'd have liked to have removed the accidental conversion from 0.0 (and indeed 0.0m and 0.0f) to enum values, but unfortunately I gather it broke too much code - even though it should never have been allowed in the first place.

The Mono mcs compiler prohibits all of these floating point conversions, although it does allow:

const int Zero = 0;
...

SomeEnum x = Zero;

despite the fact that Zero is a constant expression but not a decimal-integer-literal.

I wouldn't be surprised to see the C# specification change in the future to allow any integer constant expression with a value of 0 (i.e. to mimic mcs), but I wouldn't expect the floating point conversions to ever officially be correct. (I've been wrong before about predicting the future of C#, of course...)

people

See more on this question at Stackoverflow