C#如何声明带checked检查的switch表达式体函数
原因说明
这是C#语言规范明确定义的行为,不是编译器Bug:
checked有两种用法,作用范围完全不同:- 表达式形式:
checked(...),仅对括号内直接作为当前表达式组成部分的整数算术、类型转换运算生效,不会穿透switch表达式、lambda、本地函数的边界,覆盖不到这类结构内部的子运算。 - 语句块形式:
checked { ... },上下文覆盖块内所有文本位置的整数运算,仅不穿透lambda、本地函数、异步匿名方法的边界,switch分支、条件判断、循环内的运算都在覆盖范围内。
- 表达式形式:
- 你之前写的
checked(condition switch { ... })属于表达式形式的checked,外层仅会检查switch匹配逻辑本身的溢出,switch每个分支内部的x+y/x*y属于switch的内部子节点,不在覆盖范围内,因此不会抛异常。 SomeFunc能正常触发异常,是因为checked(x+y)中的加法就是checked括号内直接包含的运算,属于覆盖范围。
规范实现方案
不需要给switch的每个分支单独加checked,用单个checked语句块即可覆盖所有分支的溢出检查,C# 10/.NET 6下的标准写法:
static Int32 SomeFuncSwitch(Int32 x, Int32 y, UInt16 condition) { checked { return condition switch { 1 => x + y, _ => x * y }; } }
如果要保留表达式体函数(=>)的简洁写法,C# 10及以上版本支持直接将checked语句块作为表达式体:
static Int32 SomeFuncSwitch(Int32 x, Int32 y, UInt16 condition) => checked { return condition switch { 1 => x + y, _ => x * y }; };
补充:如果需要对整个项目的所有运算默认启用checked检查,可以在项目配置中添加
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>属性,不需要在代码中写任何checked块。
内容的提问来源于stack exchange,提问作者Old Skull
相关产品推荐
相关产品推荐

