为什么(以及如何)Enum的顺序会影响ToString值?

Kee*_*ker 8 .net c# enums c#-4.0

嘿伙计们,我一直有关于枚举值的"顺序"的问题.这有点难以解释,这就是为什么我写了一些代码:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

输出是:

枚举A:两两二四

Enum B:三三三四

恩生C:一一四

我的问题是:为什么!?我找不到输出的逻辑.大部分时间都有一些逻辑可以找到,所以我希望你们能够对这个问题有所了解.

我使用VS2010/.Net 4.0来编译和运行代码.

Jon*_*eet 12

行为被指定为"未定义"(我以为我刚刚发现了一个模式,但显然没有.)文档明确地将其调出:

如果多个枚举成员具有相同的基础值,并且您尝试根据其基础值检索枚举成员名称的字符串表示形式,则您的代码不应对该方法将返回的名称做出任何假设.

要么使您的枚举值不同,要么显式创建从值到所需名称的映射.


Dam*_*ver 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 
Run Code Online (Sandbox Code Playgroud)

也就是说,这些枚举值的加载是将值"1"加载三次,然后调用WriteLine.因此,我们不应该惊讶于前3个调用都会产生相同的值.

我已经尝试了一些实验,但不能指出您可以依赖的任何特定(无证)行为来预测将打印哪个值.