嘿伙计们,我一直有关于枚举值的“顺序”的问题。这有点难以解释,这就是我编写代码的原因:
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();
}
}
输出结果为:
Enum A: 二 二 二 四
Enum B: 三 三 三 四
枚举C: 一 一 一 四
我的问题是:为什么!?我找不到输出的逻辑。大部分时间都有一些逻辑可以找到,所以我希望你们能够对这个问题有所了解。
我使用VS2010 / .Net 4.0来编译和运行代码。
答案 0 :(得分:12)
行为被指定为“未定义”(我以为我刚刚发现了一种模式,但显然没有。)documentation明确地将其调出:
如果多个枚举成员具有相同的基础值,并且您尝试根据其基础值检索枚举成员名称的字符串表示形式,则您的代码不应对该方法将返回的名称做出任何假设。
使您的枚举值不同,或者明确地创建从值到所需名称的地图。
答案 1 :(得分:5)
首先要注意的是,如果你对IL进行反编译,那么对WriteLine
的调用看起来非常相似:
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
也就是说,加载这些枚举值会将值“1”加载三次,然后调用WriteLine
。所以我们不应该惊讶于前3个调用都会产生相同的值。
我尝试了一些实验,但不能指出您可以依赖的任何特定(无证件)行为来预测将打印哪个值。