C# 运算符的简化操作(二):checked 和 unchecked 运算符

02 checked 和 unchecked 运算符

考虑下面的代码:

byte b = byte.MaxValue;

b++;

Console.WriteLine(b);

byte 数据类型只能包含 0~255 的数,给 byte.MaxValue 分配一个字节,得到 255。对于 255,字节中所有可用的 8 个位都得到设置:.11111111。所以递增这个值会导致溢出,得到 0。

CLR 如何处理这个溢出取决于许多因素,包括编译器选项;所以只要有未预料到的溢出风险,就需要用某种方式确保得到我们希望的结果。

为此,C# 提供了 checked 和 unchecked 运算符。如果把一个代码块标记为checked,CLR 就会执行溢出检查,如果发生溢出,就抛出 OverflowException 异常。下面修改上述代码,使之包含 checked 运算符:

byte b = 255; 

checked

{

    b++;

}

Console.WriteLine(b);

运行这段代码,就会得到一条错误信息:

System.OverflowException: Arithmetic operation resulted in an overflow.

使用 Advance Build Settings 中的 Visual Studio 项目设置 Check for Arithmetic Overflow/Underflow,可以对所有未标记的代码进行溢出检查。也可以直接在项目文件中改变它:

<PropertyGroup>

    <OutputType>Exe</OutputType>

    <TargetFramework>netcoreapp2.0</TargetFramework>

    <CheckForOverflowUnderflow>ture</CheckForOverflowUnderflow>

</PropertryGroup>

如果要禁止溢出检查,则可以把代码标记为 unchecked:

byte b = 255; 

unchecked

{

    b++;

}

Console.WriteLine(b);

在本例中不会抛出异常,但会丢失数据——因为 byte 数据类型不能包含256,溢出的位会被丢弃,所以 b 变量得到的值是 0。

注意,unchecked 是默认行为。只有在需要把几行未检查的代码放在一个显式标记为checked 的大代码块中时,才需要显式地使用 unchecked 关键字。

注意

默认不检查上溢出和下溢出,因为执行检查会影响性能。使用 checked 作为默认设置时,每一个算术运算的结果都需要验证其值是否越界。算术运算也可以用于使用i++ 的 for 循环中。为了避免这种性能影响,最好一直不使用默认设置(Check for Arithmetic Overflow/Underflow),在需要时使用checked运算符。