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

时间:2013-12-20 18:05:43

标签: c#

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

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

1 个答案:

答案 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文章解释了一些注意事项(例如,溢出检查仅适用于直接代码块,而不适用于块内的任何函数调用)。

相关问题