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

时间:2014-07-20 16:38:16

标签: c# enums ambiguous-grammar

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

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);
}

输出:

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”?这是未定义的行为,还是我错过了一些明显的东西?

1 个答案:

答案 0 :(得分:36)

具体记录为无证行为。

编写代码的方式可能会有所不同,每次都会选择相同的东西,但documentation of Enum.ToString说明了这一点:

  

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

(我的重点)

正如评论中所提到的,不同的.NET运行时可能返回不同的值,但是未记录的行为的整个问题是它很容易因没有(看似)正当理由而改变。它可能会根据天气,时间,程序员的心情,甚至是.NET运行时的修补程序而改变。 您不能依赖未记录的行为

请注意,在您的示例中,ToString正是您要查看的内容,因为您打印该值,而后者又会将其转换为字符串。

如果您尝试进行比较,所有具有相同基础数值的枚举值都是等效的,并且您无法确定首先存储在变量中的哪一个。

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

var x = en.a;

之后无法推断您编写了en.a而不是en.ben.c因为它们都比较相等,它们都具有相同的基础值。好吧,没有创建一个读取自己来源的程序。