checked 和 unchecked 是 C# 中用于控制整数算术运算是否启用溢出检查的关键字,它们只影响编译时和运行时的整数类型(
int、
long、
short、
byte等)溢出行为,对浮点数或 decimal 无效。
什么时候会触发溢出检查?
默认情况下,C# 在 编译时的常量表达式 中启用溢出检查(即编译器会报错),但在 运行时的变量运算 中默认不检查(静默溢出)。例如:
int x = int.MaxValue + 1;→ 编译错误(常量溢出)
int y = int.MaxValue; int z = y + 1;→ 编译通过,运行时 z =
int.MinValue(回绕,无异常)
用 checked 启用运行时溢出检查
在可能溢出的代码块或表达式前加 checked,一旦发生溢出就抛出
System.OverflowException:
checked { int x = int.MaxValue + 1; } → 运行时报异常
int result = checked(a * b + c);→ 对整个表达式启用检查 适合金融计算、安全敏感逻辑等不能容忍静默回绕的场景
用 unchecked 禁用溢出检查(包括常量)
unchecked 可显式关闭检查,让常量溢出也能通过编译,并确保运行时也不抛异常:
unchecked { int x = int.MaxValue + 1; } → 编译通过,x = int.MinValue
int x = unchecked(int.MaxValue + 1);→ 同上,表达式级写法 常用于位运算、哈希计算、底层数值处理等依赖回绕行为的场合
项目级默认行为与注意事项
C# 默认是“运行时不检查”,但可通过编译器选项
/checked+或项目文件中设置
<checkforoverflowunderflow>true</checkforoverflowunderflow>全局开启运行时检查。不过更推荐按需使用
checked/
unchecked块,保持意图明确、粒度可控。注意:它们不影响引用类型或非整数类型,也不改变除法零异常等其他异常行为。
基本上就这些 —— 简单但容易忽略的底层控制机制。
