Just noticed that the unchecked context doesn't work when working with a BigInteger, for instance:
unchecked
{
// no exception, long1 assigned to -1 as expected
var long1 = (long)ulong.Parse(ulong.MaxValue.ToString());
}
unchecked
{
var bigInt = BigInteger.Parse(ulong.MaxValue.ToString());
// throws overflow exception
var long2 = (long)bigInt;
}
Any idea why that's the case? Is there something special with the way big integers are converted to other primitive integer types?
Thanks,
The C# compiler has no idea whatsoever that a BigInteger is logically an "integral type". It just sees a user-defined type with a user-defined explicit conversion to long. From the compiler's point of view,
long long2 = (long)bigInt;
is exactly the same as:
long long2 = someObject.SomeMethodWithAFunnyNameThatReturnsALong();
It has no ability to reach inside that method and tell it to stop throwing exceptions.
But when the compiler sees
int x = (int) someLong;
the compiler is generating the code doing the conversion, so it can choose to generate checked or unchecked code as it sees fit.
Remember, "checked" and "unchecked" have no effect at runtime; it's not like the CLR goes into "unchecked mode" when control enters an unchecked context. "checked" and "unchecked" are instructions to the compiler about what sort of code to generate inside the block. They only have an effect at compile time, and the compilation of the BigInt conversion to long has already happened. Its behaviour is fixed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With