【发布时间】:2026-01-10 06:05:02
【问题描述】:
在 C# 中,十进制文字 0 可以隐式转换为枚举(或基础类型为枚举的可空值)。
C# spec,GitHub 上的当前版本
隐式枚举转换 允许将 decimal_integer_literal 0 转换为任何 enum_type 以及基础类型为 enum_type 的任何 nullable_type。在里面 后一种情况下,转换是通过转换为 底层 enum_type 并包装结果(可空类型)。
ECMA-334,第 11.2.4 节隐式枚举转换
隐式枚举转换允许十进制-整数-文字 0(或 0L 等)被转换为任何枚举类型和任何 其基础类型为枚举类型的可空值类型。在里面 后一种情况下,转换是通过转换为 底层枚举类型并包装结果(第 9.3.11 节)
基于此,以下所有示例都应该是合法的。这个例子来自 Eric Lippert 的文章The Root Of All Evil, Part One。
enum E
{
X, Y, Z
}
E e1 = E.X;
E e2 = 0 | E.X;
E e3 = E.X | 0;
E e4 = E.X | 0 | 0;
E e5 = 0 | E.X | 0;
但是,正如 Eric 解释的那样,以下情况应该是非法的:
E e6 = 0 | 0 | E.X;
原因是0 | 0 | E.X 与(0 | 0) | E.X 相同,而0 | 0 不是文字,而是值为0 的编译时常量。以下情况也是如此:
E e7 = 1 - 1;
E e8 = 2 - 1 - 1 + 0;
E e9 = (0L & 1);
但是,这些都可以正常工作;在此示例中,e6、e7、e8 和 e9 的值为 E.X。
这是为什么呢?标准中是否有(更新的)规范说编译时常量为 0 也可以隐式转换为任何枚举,或者这是编译器在不完全遵循规范的情况下所做的事情?
【问题讨论】:
-
自 2006 年以来,情况可能已经发生了变化。它在哪个 C# 版本中有效,在哪个版本中无效?
-
我觉得都是一样的。适用于 .NET 框架 4.6.2 和 .NET 核心 2.1。
-
@MariusBancila 你需要对这里的语言非常谨慎......这是一个编译器的东西 - “.NET framework 4.6.2 和 .NET core 2.1”是 runtimes - 坦率地说,他们甚至没有投票权。 compiler 版本在这里很重要。
-
当然,你是对的。从 ISO-2 到 C# 7.3,我都尝试过。它们都一样。
标签: c# enums type-conversion implicit-conversion