我第一次遇到这个关键字。它做了什么,什么时候应该使用?
int multiply(int i, int j)
{
return checked(i * j);
}
答案 0 :(得分:57)
Eric Lippert分为两部分博客文章“什么是未经检查的关键字有用?”:Part 1 - Part 2
"Checked"是一个块关键字,用于启用算术溢出检查。通常,如果整数运算超过该类型可以处理的最大值或最小值,则无论如何都会进行操作,结果就像里程表一样循环。所以,例如:
byte b = byte.MaxValue;
Console.WriteLine(b); // 255 (11111111)
Console.WriteLine(++b); // 0 (00000000)
将此代码段放在checked
块中可防止溢出,而运行时会抛出OverflowException
:
checked
{
byte b = byte.MaxValue;
Console.WriteLine(b); // b=255
try
{
Console.WriteLine(++b);
}
catch (OverflowException e)
{
Console.WriteLine(e.Message); // "Arithmetic operation resulted in an overflow."
// b = 255
}
}
由于存在编译器选项/checked
,默认情况下会启用编译器检查,因此还有unchecked
关键字可防止溢出检查。
就使用情况而言,应谨慎使用溢出检查as is true of exception handling in general。要在运行时检查溢出,进行简单检查要快得多(比如一个数量级),而不是打开溢出检查:
int multiply(int i, int j)
{
if ((long)i * (long)j > int.MaxValue)
throw new InvalidOperationException("overflow");
return i*j;
}
即使对于Int64 / long,您也可以使用BigInteger
执行此操作(这仍然比使用checked
快至少一个数量级):
long multiply(long i, long j)
{
if (new System.Numerics.BigInteger(i) + j > long.MaxValue)
throw new InvalidOperationException("overflow");
return i*j;
}
还有一篇很好的Code Project文章解释了一些注意事项(例如,溢出检查仅适用于直接代码块,而不适用于块内的任何函数调用)。