在C#中,十进制字面量
根据C#规范,当前版本在GitHub上:
隐式枚举转换允许将十进制整数字面量0转换为任何枚举类型和任何基础类型为枚举类型的可空值类型。在后一种情况下,转换通过转换为基础枚举类型并包装结果(可空值类型)进行评估。
根据ECMA-334,第11.2.4节隐式枚举转换:
隐式枚举转换允许将十进制整数字面量0(或0L等)转换为任何枚举类型和任何基础类型为枚举类型的可空值类型。在后一种情况下,转换通过转换为基础枚举类型并包装结果(§9.3.11)进行评估。
基于此,以下所有示例都应该合法。此示例来自Eric Lippert的文章The Root Of All Evil, Part One。
然而,正如Eric所解释的,以下情况应该是非法的:
0
可以隐式转换为枚举类型(或基础类型为枚举的可为空类型)。根据C#规范,当前版本在GitHub上:
隐式枚举转换允许将十进制整数字面量0转换为任何枚举类型和任何基础类型为枚举类型的可空值类型。在后一种情况下,转换通过转换为基础枚举类型并包装结果(可空值类型)进行评估。
根据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
不是一个字面量(literal),而是一个编译时常量,其值为0。以下情况也是如此:
E e7 = 1 - 1;
E e8 = 2 - 1 - 1 + 0;
E e9 = (0L & 1);
然而,这些都可以正常工作;在此示例中,e6
、e7
、e8
和e9
的值均为E.X
。
为什么会这样?是否有一个(更新的)标准规范,指出编译时常量为0的枚举也可以隐式转换为任何枚举类型,或者这是编译器在不完全遵循规范的情况下进行的操作?