Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
504 views
in Technique[技术] by (71.8m points)

What is the C# "checked" keyword for?

I just came across this keyword for the first time. What does it do, and when should it be used?

int multiply(int i, int j)
{
    return checked(i * j);
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Eric Lippert has a two-part blog post "What is the unchecked keyword good for?": Part 1 -- Part 2


"Checked" is a block keyword that enables arithmetic overflow checking. Normally, if an integer operation exceeds the maximum or minimum value that the type can handle, the operation proceeds anyway, and the result just cycles like an odometer. So, for example:

byte b = byte.MaxValue;
Console.WriteLine(b);       // 255  (11111111)
Console.WriteLine(++b);     // 0    (00000000)

Placing this snippet in a checked block prevents the overflow, and instead the runtime throws an 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
    }
}

And since there's a compiler option /checked, which turns compiler checking on by default, there is also the unchecked keyword which prevents overflow checking.


As far as usage, overflow checking should be used sparingly, as is true of exception handling in general. To check for an overflow at runtime, it's significantly faster (like, an order of magnitude) to do a simple check, rather than to turn on overflow checking:

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

You can do this even for Int64/long, using BigInteger (this can be still at least an order of magnitude faster than using checked):

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

There's also a good Code Project article on this that explains some caveats (eg, the overflow check only applies to the immediate code block, not to any function calls inside the block).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...