Welcome to MSDN Blogs Sign in | Join | Help

More peculiarites of enum

The well known (or moderately known fact): C# enums can contain any value supported by its base type and not just the ones specified in the enum. Lets consider the following enum.

enum WeekDay
{
    Monday = 1,
    Tuesday = 2,
    Wednesday = 3,
    Thursday = 4,
    Friday = 5,
    Saturday = 6,
    Sunday = 7
}

Even though the enum supports values from 1 to 7 you can do the following.

WeekDay day = (WeekDay)40;
Console.WriteLine(day);

This prints out 40 without any error.

Now comes the lesser known fact: C# 1.2 spec sez "An Implicit enumeration conversion permits the decimal-integer-literal 0 to be converted to enum-type". This means the following is valid code

WeekDay day = 0;
Console.WriteLine(day);

Note that even though 0 is not supported it is implicitely casted to the enum!!! No idea why this is supported.

Published Tuesday, January 09, 2007 1:35 PM by abhinaba
Filed under:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# re: More peculiarites of enum

Tuesday, January 09, 2007 4:56 AM by zproxy

An enum value of 0 should be always reserved for None, Empty, Default or alike, thus assigning 0 allows to initialize the enum. It should have the same effect as default(MyEnumType).

"Do name the zero value of flags enumerations None. For a flags enumeration, the value must always mean all flags are cleared.

Note"

http://msdn2.microsoft.com/en-us/library/ms229062.aspx

# re: More peculiarites of enum

Tuesday, January 09, 2007 5:01 AM by abhinaba

You have pointed to Flags enumeration where it makes perfect sense to have a zero.

But in our case this is not a bit flag and there is no default or empty weekday, nor can you have monday and tuesday at the same time (with an OR).

# re: More peculiarites of enum

Tuesday, January 09, 2007 6:21 AM by Sam Judson

Enumerations are a CLR value type, stored in the method stack as an Int32, which defaults to 0 anyway - the following two code segments have exactly the same end result:

WeekDay day;

WeekDay day = 0;

The C# compiler will however consider the first variable 'unitialised'.

# re: More peculiarites of enum

Tuesday, January 09, 2007 8:36 AM by Peter Ritchie

I think it's less to do with the guideline of always defining a enum member with the value 0 than to do with the fact that an enum will always initialize to 0 before the first assignment.  There's really no point in throwing an error for assigning a value (0) to a enum type when that same value was used to initialize it, without error.

An in fact, in your example "Weekday day = 0;", the assignment of zero (0) is redundant; day will have been initialized with 0 already.  It could be that this is "supported" because it is optimized out (I'm not sure).

# re: More peculiarites of enum

Tuesday, January 16, 2007 5:33 PM by Mark Steward

I'm pretty sure it would have to be because (as you mentioned) Enums are used for flags as well as for lists.

But of course, a lot of enums come from protocol definitions, so having to mentally add a zero case to every enum would be onerous, for very little extra protection (since enums are initialised to 0, it's not risky like having a zero pointer).

# re: More peculiarites of enum

Saturday, January 20, 2007 11:15 PM by Shahar

Peter Ritchie:

C# requires that you initialize any and all local variables.

You are confusing this with member variables that do not have to be initialized.

(This is a C# thing, not a CLR/MSIL thing - the CLR, as somebody mentioned, will automatically initialize it if the code does not do that..)

# re: More peculiarites of enum

Friday, November 23, 2007 1:17 PM by Michael Buen

can you request to Visual Studio 2008 team, to straight out C# 3.0 treatment of enum?  because it is very confusing.

it is not clean to have 0 moonlighting as enum.

an example:

enum PgType { Varchar, Date, Integer };

static void Main()

{

AddField("Name", "Michael Buen");

AddField("JobToSeek", PgType.Varchar);

AddField("Age", 20);

AddField("WorkExperience", 0);

}

static void AddField(string name, PgType t)

{

Console.WriteLine(name + ": just add field");

}

static void AddField(string name, object value)

{

Console.WriteLine(name + ": add field and assign value at the same time, also get the type");

}

output is:

Name: add field and assign value at the same time, also get the type

JobToSeek: just add field

Age: add field and assign value at the same time, also get the type

WorkExperience: just add field

Note: the WorkExperience should be: add field and assign a value at the same time.

to illustrate again the problem:

http://plus.kaist.ac.kr/~shoh/postgresql/Npgsql/apidocs/Npgsql.NpgsqlParameterCollection.Add_overload_3.html

http://cleveralias.blogs.com/thought_spearmints/2004/01/more_c_enum_wac.html

eric gunnerson's reasoning:

   if ((myVar & MyEnumName.ColorRed) != (MyEnumName) 0)

   which we thought was difficult to read. One alernative was to define a zero entry:

   if ((myVar & MyEnumName.ColorRed) != MyEnumName.NoBitsSet)

   which was also ugly.

   We therefore decided to relax our rules a bit, and permit an implicit conversion from the literal zero to any enum type, which allows you to write:

   if ((myVar & MyEnumName.ColorRed) != 0)

   which is why PlayingCard(0, 0) works.

that relaxing rule was favored because of bitwise elegance, but the C# team didn't see the drastic effect on programmer's strong faith on C#'s strong-typing.  0 should resolve to object if there is no integer overload function.  0 should never become an enum type in anyways, just like the value 20 should resolve to object, not enum.  i hope they will fix this in C# 3.0.  C# enum zero looks like a gotcha, because it always needs an explanation

# re: More peculiarites of enum

Saturday, December 08, 2007 11:38 PM by Michael Buen

they should have make @0 to indicate enum zero.   0 shouldn't be implicitly cast to in any ways, just like any number.

VS team should have make this:

  if ((myVar & MyEnumName.ColorRed) != 0)

to:

  if ((myVar & MyEnumName.ColorRed) != @0)

so there will be no more implicitly casted zero to enum gotcha :-)

# re: More peculiarites of enum

Saturday, December 08, 2007 11:41 PM by Michael Buen

they should have make @0 to indicate enum zero.   0 shouldn't be implicitly cast to in any ways, just like any number.

VS team should have make this:

  if ((myVar & MyEnumName.ColorRed) != 0)

to:

  if ((myVar & MyEnumName.ColorRed) != @0)

so there will be no more implicitly casted zero to enum gotcha :-)

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
 
Page view tracker