C# Checked运算符方法 C#如何防止算术溢出

来源:这里教程网 时间:2026-02-21 17:43:08 作者:

什么时候该用
checked
而不是依赖默认行为

默认情况下,C# 对整数算术溢出是「静默忽略」的——比如

int.MaxValue + 1
会绕回
int.MinValue
,不报错也不警告。这在金融、计费、索引计算等场景极危险。只有当你明确需要检测并中断非法运算时,才启用
checked
;否则保持默认(即
unchecked
上下文)更高效。

常见触发点包括:用户输入参与的金额累加、数组长度动态计算、循环步长叠加、ID 生成器递增。

checked
块和
checked
表达式的区别与选择

checked
可以修饰语句块或单个表达式,二者语义一致,但作用域不同:

checked { int x = int.MaxValue + 1; }
—— 整个块内所有整数运算都受检
int x = checked(int.MaxValue + 1);
—— 仅括号内表达式受检,不影响前后代码
若写成
int x = checked(int.MaxValue) + 1;
,则
checked
只包住
int.MaxValue
(无意义),加法仍不受检——这是典型误用

编译器选项
/checked+
的实际影响

项目属性中勾选「检查算术溢出/下溢」,等价于整个编译单元默认进入

checked
上下文。但注意:

它只影响
int
short
long
byte
等整型,对
float
double
decimal
无效(
decimal
本身就会溢出抛异常)
它不能覆盖显式写的
unchecked
块——后者优先级更高
开启后可能暴露隐藏 bug,比如旧代码里依赖绕回逻辑做哈希或位掩码,此时会直接崩掉

捕获
OverflowException
的正确姿势

checked
触发的是
OverflowException
,不是
ArithmeticException
ArgumentException
,别抓错类型:

try
{
    int result = checked(1000000 * 1000000);
}
catch (OverflowException)
{
    // 正确:专门处理溢出
}
catch (Exception ex) when (ex is not OverflowException)
{
    // 不建议:泛捕获掩盖问题
}

注意:.NET 5+ 中

OverflowException
是非致命异常,可安全捕获;但在性能敏感路径(如 inner loop)中频繁抛异常代价高,应优先用预检查(如比较操作数与
int.MaxValue - operand
)替代
checked
+ 异常。

最易被忽略的一点:

checked
对引用类型、浮点数、
decimal
加减乘除完全无作用——它只约束有符号/无符号整型的四则与一元运算。

相关推荐

热文推荐