I have problems with the "order" of the values of an enum. It's a little difficult to explain, that's why I wrote up some code:
class Program
{
public enum EnumA
{
One = 1,
Two = One,
Three = Two,
Four = 4
}
public enum EnumB
{
One = 1,
Two = One,
Four = 4,
Three = Two
}
public enum EnumC
{
Two = One,
Three = Two,
Four = 4,
One = 1
}
static void Main(string[] args)
{
Console.WriteLine("Enum A:");
Console.WriteLine(EnumA.One);
Console.WriteLine(EnumA.Two);
Console.WriteLine(EnumA.Three);
Console.WriteLine(EnumA.Four);
Console.WriteLine();
Console.WriteLine("Enum B:");
Console.WriteLine(EnumB.One);
Console.WriteLine(EnumB.Two);
Console.WriteLine(EnumB.Three);
Console.WriteLine(EnumB.Four);
Console.WriteLine();
Console.WriteLine("Enum C:");
Console.WriteLine(EnumC.One);
Console.WriteLine(EnumC.Two);
Console.WriteLine(EnumC.Three);
Console.WriteLine(EnumC.Four);
Console.WriteLine();
Console.ReadLine();
}
}
The output is:
Enum A: Two Two Two Four
Enum B: Three Three Three Four
Enum C: One One One Four
My question is: WHY!? I can't find the logic to the output. Most of the time there is some logic to be found, so I hope you guys can shine some light on this issue.
I used VS2010 / .Net 4.0 to compile and run the code.
The behaviour is specified to be "undefined" (I thought I'd spotted a pattern just now, but apparently not.) The documentation explicitly calls this out:
If multiple enumeration members have the same underlying value and you attempt to retrieve the string representation of an enumeration member's name based on its underlying value, your code should not make any assumptions about which name the method will return.
Either make your enum values distinct, or explicitly create a map from value to desired name.
The first thing to observe, if you decompile the IL, is that the calls to WriteLine
all look remarkably similar:
L_000c: ldc.i4.1
L_000d: box ConsoleApplication2.Program/EnumA
L_0012: call void [mscorlib]System.Console::WriteLine(object)
L_0017: nop
L_0018: ldc.i4.1
L_0019: box ConsoleApplication2.Program/EnumA
L_001e: call void [mscorlib]System.Console::WriteLine(object)
L_0023: nop
L_0024: ldc.i4.1
L_0025: box ConsoleApplication2.Program/EnumA
L_002a: call void [mscorlib]System.Console::WriteLine(object)
L_002f: nop
L_0030: ldc.i4.4
L_0031: box ConsoleApplication2.Program/EnumA
L_0036: call void [mscorlib]System.Console::WriteLine(object)
L_003b: nop
L_003c: call void [mscorlib]System.Console::WriteLine()
L_0041: nop
That is, the loading of these enum values is loading the value "1" three times, and then calling WriteLine
. So we should not be surprised that the 1st 3 calls all result in the same value.
I've tried a few experiments, but can't point to any particular (undocumented) behaviour you can rely on to predict which value will be printed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With