Have you ever tried to implicitly cast a larger data type into a smaller type (as far as the number of bits) through a plain old assignment? c# wont let you do it!
In this case the long’s value of 5 will definitely fit into an int but the compiler will still give you a no-no. Its avoiding possibly dropping some of the 64 bits when assigning the value to 32 bits. Not to worry, you can always do the explicit cast.
int myInt;
long myLong = 5;
myInt = (int)myLong;
This lets the compiler know that you purposely want to do the cast even though bits may be lost. But wait, what happens if the long’s value is too big to fit into an int and you do the explicit cast anyway without knowing. Well the default behavior is to do the cast, drop some bits and keep quiet about it. Unfortunately your value in the int probably wont be what you wanted. Sadly you wont know about it until you try to use it.
The same thing is true in the situation below.
int c = 2147483647; //will fit in 32 bits
int d = 2147483647; //will fit in 32 bits
myInt = c * d; //product wont fit
No exception will be thrown. To remedy this situation you can use a checked block. By wrapping the code which may drop or overflow bits in a checked block, you can for an force an OverflowException to be thrown if it occurs.
//the setup
int myInt;
long myLong = 2147483648; //too big to fit in an int
myInt = (int)myLong;
try
{
checked
{
myInt = (int)myLong;
//bits were lost OverflowException is thrown
}
//never will reach this
}
catch (OverflowException ex)
{
//do something
}
Using the checked block will work for either of the cases described above. There is also an unchecked block to say not to check for overflow and you can also create checked and unchecked expressions. There is even a compiler option to turn checked or unchecked on globally for your code (Project Properties => Build tab => Advanced button).
Using the checked or unchecked blocks in your code will override any compiler option for that block of code.
posted @ Wednesday, July 08, 2009 2:12 PM