checked 关键字用于对整型算术运算和转换显式启用溢出检查。
默认情况下,如果表达式仅包含常数值,且产生的值在目标类型范围之外,则它会导致编译器错误。 如果表达式包含一个或多个非常数值,则编译器不检测溢出。 在下面的示例中,计算赋给 i2 的表达式不会导致编译器错误。
C#
// The following example causes compiler error CS0220 because 2147483647 // is the maximum value for integers. //int i1 = 2147483647 + 10; // The following example, which includes variable ten, does not cause // a compiler error. int ten = 10; int i2 = 2147483647 + ten; // By default, the overflow in the previous statement also does // not cause a run-time exception. The following line displays // -2,147,483,639 as the sum of 2,147,483,647 and 10. Console.WriteLine(i2);
默认情况下,在运行时也不检查这些非常数表达式是否溢出,这些表达式不引发溢出异常。 上面的示例显示 -2,147,483,639 作为两个正整数之和。
可以通过编译器选项、环境配置或使用 checked 关键字来启用溢出检查。 下面的示例演示如何使用 checked 表达式或checked 块,在运行时检测由前面的求和计算导致的溢出。 两个示例都引发溢出异常。
C#
// If the previous sum is attempted in a checked environment, an // OverflowException error is raised. // Checked expression. Console.WriteLine(checked(2147483647 + ten)); // Checked block. checked { int i3 = 2147483647 + ten; Console.WriteLine(i3); }
可以使用 unchecked 关键字阻止溢出检查。
此示例演示如何使用 checked 启用运行时溢出检查。
C#
class OverFlowTest { // Set maxIntValue to the maximum value for integers. static int maxIntValue = 2147483647; // Using a checked expression. static int CheckedMethod() { int z = 0; try { // The following line raises an exception because it is checked. z = checked(maxIntValue + 10); } catch (System.OverflowException e) { // The following line displays information about the error. Console.WriteLine("CHECKED and CAUGHT: " + e.ToString()); } // The value of z is still 0. return z; } // Using an unchecked expression. static int UncheckedMethod() { int z = 0; try { // The following calculation is unchecked and will not // raise an exception. z = maxIntValue + 10; } catch (System.OverflowException e) { // The following line will not be executed. Console.WriteLine("UNCHECKED and CAUGHT: " + e.ToString()); } // Because of the undetected overflow, the sum of 2147483647 + 10 is // returned as -2147483639. return z; } static void Main() { Console.WriteLine("\nCHECKED output value is: {0}", CheckedMethod()); Console.WriteLine("UNCHECKED output value is: {0}", UncheckedMethod()); } /* Output: CHECKED and CAUGHT: System.OverflowException: Arithmetic operation resulted in an overflow. at ConsoleApplication1.OverFlowTest.CheckedMethod() CHECKED output value is: 0 UNCHECKED output value is: -2147483639 */ }
下面示例演示了一个有检查的 C# 强制转换,它尝试将 Int32::MaxValue 转换为 Byte 值。请注意,虽然整数值超出了目标 Byte 数据类型的范围,但是转换不会引发 OverflowException。C#// The integer value is set to 2147483647. int myInt = int.MaxValue; try {checked{byte myByte = (byte)myInt; Console.WriteLine("The byte value is {0}.", myByte);}} catch (OverflowException) { Console.WriteLine("Unable to convert {0} to a byte.", myInt); } // The value of MyByte is 255, the maximum value of a Byte. // overflow exception is thrown.上面的示例演示了使用 Visual Basic 中的有检查 CByte 函数的显式转换,以及在 C# 中使用 checked 关键字的有检查强制转换的显式转换。此示例尝试将 Int32::MaxValue 转换为 Byte 值。但是,因为 Int32::MaxValue 超出了 Byte 数据类型的范围,所以引发了 OverflowException。