C#中switch支持TypeSafeEnum隐式转int但不支持转Enum的原因
问题原因
这个差异本质是C# switch语法的两套匹配规则对用户自定义隐式转换的支持范围不同:
第一种int实现的场景可正常编译的原因
int属于C# switch传统语法原生支持的内置类型(同类型还包括bool、char、string、内置枚举等)。当switch的输入参数存在到这类内置类型的用户自定义隐式转换时,编译器会自动触发类型提升逻辑:将输入的TypeSafeEnum实例隐式转换为int,再和case后的int常量做等值匹配,因此可以正常运行。第二种自定义枚举实现的场景报错的原因
你定义的TypeSafeEnum2.Enum是用户自定义的枚举类型,不属于switch传统语法支持自动类型提升的内置类型范畴,此时编译器会走C# 7.0+引入的常量模式匹配规则。
该规则下,编译器默认会尝试将case后的常量值转换为switch输入参数的类型(也就是尝试把TypeSafeEnum2.Enum类型的常量转为TypeSafeEnum2类型),但你只实现了TypeSafeEnum2到TypeSafeEnum2.Enum的单向隐式转换,没有反向转换的逻辑,因此会抛出「无法隐式转换类型」的错误。
解决方案
你注释中提到的显式转换写法是最推荐的方案,不会暴露额外的类型转换逻辑,符合实现细节封装的要求:
bool test(TypeSafeEnum2 tse) { switch ((TypeSafeEnum2.Enum)tse) { case TypeSafeEnum2.Enum.Foo: case TypeSafeEnum2.Enum.Bar: return true; } return false; }
如果希望保持和第一种写法相同的调用形式,也可以给TypeSafeEnum2补充反向隐式转换运算符:
public static implicit operator TypeSafeEnum2(Enum e) => new TypeSafeEnum2 { Value = e, Name = e.ToString() };
内容的提问来源于stack exchange,提问作者malat
相关产品推荐
相关产品推荐

