Why does this throw an OverflowException?

Xenoprimate picture Xenoprimate · Jan 7, 2014 · Viewed 7.3k times · Source

I have the following code in a method to convert any number in to a byte:

try {
    return (byte) Convert.ChangeType(operand.RealValue, TypeCode.Byte);
}
catch (OverflowException) {
    if (AllowArithmeticOverflow) {
        unchecked {
            decimal d = Convert.ToDecimal(operand.RealValue);
            return (byte) d;
        }
    }

    throw;
}

In this code, operand.RealValue is expected to be any number. For the example I'm testing with, it's an sbyte with the value -13 (verified with the debugger). I can step through in the debugger and get to the line return (byte) d; ... At which point an OverflowException is thrown, despite it being in the unchecked block.

So... What gives?

Also, if you're looking at my implementation and wondering what the hell I'm doing - it's the result of all the gymnastics I've tried so far to not get this exception. Must succinct answer wins :)

Note: The exception message is as follows:

System.OverflowException: Value was either too large or too small for an unsigned byte. ---> System.OverflowException: Value was either too large or too small for a UInt32.

Answer

Mike Dinescu picture Mike Dinescu · Jan 7, 2014

Obviously there is no way to interpret -13 as a byte. At least not unless you specify some extra context. Perhaps you mean to treat -13 as an unsigned char (value between -128 and 127) and then reinterpret the bits as a signed char (byte).

If that's what you are trying to do then you could use the BitConverter class.