Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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#?

like image 326
feO2x Avatar asked May 20 '14 14:05

feO2x


People also ask

Do enum values start at 0 or 1?

Enum ValuesThe first member of an enum will be 0, and the value of each successive enum member is increased by 1. You can assign different values to enum member. A change in the default value of an enum member will automatically assign incremental values to the other members sequentially.

Can we add new enumeration value by runtime?

The only way to create one of these structs is to call the constructor that takes the value as a parameter.

Can an enum have one value?

With an enum type with only one value, most developers will not expect that (UserIDEnum)42 is used, since it's not a "defined" value of the enum.

Can enums have numbers?

Numeric enums are number-based enums i.e. they store string values as numbers. Enums are always assigned numeric values when they are stored. The first value always takes the numeric value of 0, while the other values in the enum are incremented by 1.


1 Answers

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

like image 197
Jon Skeet Avatar answered Sep 24 '22 22:09

Jon Skeet