为什么switch for enum接受隐式转换为0但是对于任何其他整数都没有?
有一个:
enum SomeEnum { A = 0, B = 1, C = 2 }
现在编译器允许我写:
SomeEnum x = SomeEnum.A; switch(x) { case 0: // <--- Considered SomeEnum.A break; case SomeEnum.B: break; case SomeEnum.C: break; default: break; }
0
被认为是SomeItems.A
。 但我写不出来:
SomeEnum x = SomeEnum.A; switch(x) { case 0: break; case 1: // <--- Here is a compilation error. break; case SomeEnum.C: break; default: break; }
为什么0
只存在隐式转换?
来自ECMA-334(C#语言规范)
13.1.3隐式枚举转换
隐式枚举转换允许将decimal-integer-literal 0转换为任何枚举类型。
枚举的默认值为0
并且在编译时已知这是为什么在switch语句中允许它的原因。 对于0
以外的0
,在编译时无法确定该值是否存在于枚举中。
枚举(C#参考)
为新版本的枚举分配其他值或更改枚举成员的值可能会导致依赖源代码出现问题。 通常情况是在switch语句中使用枚举值,并且如果在枚举类型中添加了其他元素,则默认值的测试可以意外地返回true。
我还要补充一点,在switch
语句中使用0
而不是精确enum
的语法可能会出错。 请考虑以下代码:
enum TestEnum { NA = 0, A }
然后
var e = TestEnum.NA; switch(e) { case 0: { break; } case TestEnum.A: { break; } }
这编译并运行良好。 但是,如果由于某种原因, enum
声明更改为
enum TestEnum { NA = 1, A }
一切都会破碎。
虽然在大多数情况下, enum
的默认值为0
,因此可能会出现这种语法,我会使用确切的enum
。