我检查了关于枚举的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”?这是未定义的行为,还是我错过了一些明显的东西?
答案 0 :(得分:36)
具体记录为无证行为。
编写代码的方式可能会有所不同,每次都会选择相同的东西,但documentation of Enum.ToString说明了这一点:
如果多个枚举成员具有相同的基础值,并且您尝试根据其基础值检索枚举成员名称的字符串表示形式,则您的代码不应对该方法将返回的名称做出任何假设。 /强>
(我的重点)
正如评论中所提到的,不同的.NET运行时可能返回不同的值,但是未记录的行为的整个问题是它很容易因没有(看似)正当理由而改变。它可能会根据天气,时间,程序员的心情,甚至是.NET运行时的修补程序而改变。 您不能依赖未记录的行为。
请注意,在您的示例中,ToString
正是您要查看的内容,因为您打印该值,而后者又会将其转换为字符串。
如果您尝试进行比较,所有具有相同基础数值的枚举值都是等效的,并且您无法确定首先存储在变量中的哪一个。
换句话说,如果你这样做:
var x = en.a;
之后无法推断您编写了en.a
而不是en.b
或en.c
因为它们都比较相等,它们都具有相同的基础值。好吧,没有创建一个读取自己来源的程序。