如何在C#中解决模糊的枚举值?

How are ambiguous enum values resolved in C#?

我检查了C语言规范中有关枚举的部分,但无法解释以下代码的输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
enum en {
    a = 1, b = 1, c = 1,
    d = 2, e = 2, f = 2,
    g = 3, h = 3, i = 3,
    j = 4, k = 4, l = 4
}

en[] list = new en[] {
    en.a, en.b, en.c,
    en.d, en.e, en.f,
    en.g, en.h, en.i,
    en.j, en.k, en.l
};
foreach (en ele in list) {
    Console.WriteLine("{1}: {0}", (int)ele, ele);
}

它输出:

1
2
3
4
5
6
7
8
9
10
11
12
c: 1
c: 1
c: 1
d: 2
d: 2
d: 2
g: 3
g: 3
g: 3
k: 4
k: 4
k: 4

现在,为什么要选择第三个"1",第一个"2"和"3",而第二个"4"?这是未定义的行为,还是我遗漏了一些明显的东西?


这被专门记录为无文件证明的行为。

在编写代码的过程中,可能会有一些东西每次都会选择相同的东西,但enum.toString的文档中说明了这一点:

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.

(我的重点)

正如在注释中提到的,不同的.NET运行时可能返回不同的值,但未记录的行为的整个问题是,它很容易因为没有(似乎)好的理由而发生更改。它可能会根据天气、时间、程序员的心情,甚至在.NET运行时的修补程序中发生变化。你不能依赖非法行为。

请注意,在您的示例中,ToString正是您希望看到的内容,因为您正在打印值,这反过来会将其转换为字符串。

如果尝试进行比较,则具有相同基础数值的所有枚举值都是等效的,并且不能首先分辨存储在变量中的枚举值。

换句话说,如果你这样做:

1
var x = en.a;

后来没有办法推断你写了en.a而不是en.ben.c,因为它们都比较相等,它们都具有相同的潜在价值。嗯,除了创建一个读取自己源代码的程序。