为何C#模式匹配中不同分支返回值会被推导为float类型?
C# Switch表达式类型推导疑问解析
先看你给出的问题代码:
bool v = false; object x = v switch { true => 0.0f, false => 100L, };
这段代码里,switch分支分别返回float和long类型,你预期两个分支会各自装箱为object后赋值给x,但实际编译器把整个switch表达式的类型推导成了float,导致100L被隐式转成float再装箱,和预期不符。
而显式装箱后的代码就能正常保留各自的原始类型:
object x = v switch { true => 0.0f as object, false => 100L as object, };
这不是C#的bug,完全是编译器的类型推导规则导致的:
- Switch表达式的类型推导逻辑是先找所有分支返回值的公共类型,而不是直接对齐赋值目标的
object类型。 - 对于数值类型,C#会按照隐式转换的优先级找最小公共兼容类型。
long可以隐式转换为float(注意这个转换会丢失整数精度),所以编译器判定整个switch表达式的类型是float,最后把这个float值装箱成object赋值给x。 - 当你给每个分支显式加上
as object后,所有分支的返回类型都是object,switch表达式的类型自然就是object,两个分支的值会各自装箱,保留原始的float和long类型。
另外还有一种写法也能达到同样效果,就是直接强制转换为object:
object x = v switch { true => (object)0.0f, false => (object)100L, };
内容的提问来源于stack exchange,提问作者John Smith
相关产品推荐
相关产品推荐

