views:

753

answers:

2
class Program
{
    static void Main(string[] args)
    {
        String value = "Two";
        Type enumType = typeof(Numbers);
        Numbers number = (Numbers)Enum.Parse(enumType, value);
        Console.WriteLine(Enum.Parse(enumType, value));
    }

    public enum Numbers : int
    {
        One,
        Two,
        Three,
        Four,
        FirstValue = 1
    }
}

This is a simplified version of an enum I use in an application. The reason to why some of the enum names doesn't have a value is because I do Enum.Parse with their names as argument, while the ones with a value is parsed from an int.

If you would step through the code above and investigate the 'number' variable, you would see that it in fact is 'Two', but the output in console is 'FirstValue'. At this point I can't see why, do you?

Okay, the solution is simple - just give the valueless enums a value. But I'm still curious.

+8  A: 

I suspect that both FirstValue and Two have an internal value of 1, so the system doesn't know which string to output.

public enum Numbers : int
{
    One, // defaults to 0
    Two, // defaults to 1
    Three, // defaults to 2
    Four, // defaults to 3
    FirstValue = 1 // forced to 1
}

There is a unique integer value for every enum value, but there is not a unique enum value for every integer value.

When you parse "two", it gets stored internally as the integer 1. Then when you try and convert it back to a string, depending on the technique used to lookup that name, you could get either "Two" or "FirstValue". As you stated, the solution is to give every enum value a defined integer value.

Eclipse
Why doesn't this cause a compiler error?
BC
There are perfectly legitimate reasons why you might want to have the same enum name map to a single value. This is especially true of enums used for flags.
Eclipse
Portablenut
Note that the string returned is not _guaranteed_ to be the same *even in the same process* - if you rely on this in some way it's a bug waiting to happen
ShuggyCoUk
+2  A: 

Here is an interesting twist to your problem, try the following Enum...

public enum Numbers : int
{
    One,
    Two,
    Four,
    FirstValue = 1
}

The console.WriteLine(...) will now print "Two"!

Both Two and FirstValue represent the same number 1 but the actual value seen depends on how the number was converted to its string representation and vice-versa.

The Enum class uses reflection to get the names of the numbers and then stores them in arrays but it sorts the the whole thing before it does so. Then Enum.ToString() does a binary search on the sorted values to get the string representation. Due to the way this is done you may get a different result depending on the number of elements you have in the enumeration!

Now as for the value "seen" in VS I suspect the debugger visualizer for enums uses an algorithm of its own which corrects(?) this bug.

SDX2000
interesting observation!
Sergio Acosta