checked和unchecked操作符用于整型算术运算时控制当前环境中的溢出检查。下列运算参与了checked和uncheced检查:
●预定义的++和--:一元操作符,当其操作数类型为整型时。
●预定义的-:一元操作符,当其操作数为整型数时。
●预定义的+、-、*、/等二元操作符,当两个操作数数据类型都是整型。
●从一种整型到另一种整型地显式数据转换。
当上述运算之一产生一个目标类型无法表示的大数时,在使用了checked操作符的表达式中,如果运算是一个常量表达式,则产生运行时错误,否则,当运行时执行该运算时会溢出异常。而在使用了uncheced操作符的表达式中,返回值被截掉不符合目标类型的高位。
如果非常量表达式没有被任何checked或unchecked操作符或语句所包括时,运行时计算该表达式的值,是否会产生溢出,依据于外部因素,如编译器状态、执行环境参数等。而对于一个常量表达式而言,总是默认为进行溢出检查。
使用了unchecked操作符后,溢出的发生不会导致编译错误。但这往往会出现一些不可预期的结果,所以使用unchecked操作符要小心。
下面的例子说明了checked和unchecked操作符的用法:
class Test
{
static int x=1000000;
static int y=1000000;
static intF(){
return checked(x*y); //编译错误,抛出异常
}
static int G(){
return unchecked(x*y); //返回值为-727379968
}
static int H(){
return x*y; //依赖于编译时的默认情况
}
}
由于编译时没有对任何表达式进行计算,因此不会产生编译错误。当程序运行时,调用F方法会抛出一个OverFlowException异常,而调用G方法则返回-727379968(超出结果范围的低32位)。H方法是否抛出异常则要看编译环境的默认情况了,调用它的结果有可能与F相同,也有可能与G相同。而对于常量表达式则是另一种情况:
class Test
{
const int x=1000000;
const int y=1000000;
static int F(){
return checked(x*y); //编译错误,溢出
}
static int G(){
return unchecked(x*Y); //返回值为-727379968
}
static int H(){
return x*y;
}
}
当计算F和H方法中的常量表达式时发生溢出,由于是在checked环境中,那么在编译时就报告错误。当计算G方法中的常量表达式时,也会发生溢出,但不会报告错误。
checked和unchecked操作符只影响置于其后括号之中运算的溢出检查。它们不会影响作为表达式结果的被调用的方法成员。例如:
class Test
{
static int F(int x,int y){
return x*y;
}
static int G(){
return checked(F(1000000,1000000));
}
}
其中,G方法中的checked不会影响函数F方法中的x*y运算,因此,x*y运算在默认溢出检查的上下文中。
本文来自编程入门网:http://www.bianceng.cn/Programming/csharp/200709/4379.htm