c# - 如何在 C# 中解决不明确的枚举值?

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

最佳答案

这被明确记录为未记录的行为。

代码的编写方式可能会导致每次都选择相同的东西,但是 documentation of 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 正是您要查看的内容,因为您正在打印 值,然后将其转换为字符串。

如果您尝试进行比较,所有具有相同基础数值的枚举值都是等价的,您无法分辨出您首先将哪个存储在变量中。

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

var x = en.a;

事后无法推断您写的是 en.a 而不是 en.ben.c 因为它们都是比较的相等,它们都具有相同的潜在值(value)。好吧,除了创建一个读取自己源代码的程序。

关于c# - 如何在 C# 中解决不明确的枚举值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24852609/

相关文章:

c# - 在客户端和服务器 wcf 服务上使用自定义数据类型

c++ - 为什么作用域枚举默认支持运算符 '<'?

enums - 当枚举变体已知时解包内部类型

c# - WPF 数据绑定(bind)到带有枚举键的字典

处理歧义的算法或数据结构

c# - 如何避免文件阻塞

c# - 异步 HttpHandler 的请求是否可以无异常地中断?

parsing - 解决 LALR 歧义

c# - 这行来自 ILSpy 反编译器的代码是否有效?

parsing - 判断 BNF 语法是否有歧义的最简单方法是什么?