什么是C#“checked”关键字?

我刚刚第一次遇到这个关键字。 它做什么,什么时候应该使用?

int multiply(int i, int j) { return checked(i * j); } 

Eric Lippert有一个由两部分组成的博客文章“什么是未经检查的关键词?”: 第1 部分 – 第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关键字可以防止溢出检查。


就使用情况而言,应谨慎使用溢出检查,一般情况下也应使用exception处理 。 要在运行时检查溢出,进行简单检查要快得多(比如一个数量级),而不是打开溢出检查:

 int multiply(int i, int j) { if ((long)int * (long)j > int.MaxValue) throw new InvalidOperationException("overflow"); return i*j; } 

您甚至可以使用BigInteger对Int64 / long执行此操作(这仍然比使用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文章解释了一些注意事项(例如,溢出检查仅适用于直接代码块,而不适用于块内的任何函数调用)。