I think this is a subtlety of the unbox
and unbox.any
IL instructions.
From ECMA 335, section III.4.32 (unbox
operation - unbox.any
is similar)
Exceptions:
System.InvalidCastException
is thrown if obj is not a boxed value type, valuetype is aNullable<T>
and obj is not a boxedT
, or if the type of the value contained in obj is not verifier-assignable-to (III.1.8.2.3) valuetype.
So for example, in this case:
Sex e = Sex.Male;
object o = e;
int? i = (int?)o;
it fails entirely correctly - because valuetype is Nullable<int>
and the value of obj is not a boxed int
. The "verifier-assignable-to" part doesn't apply for the Nullable<T>
case.
I doubt that any of this behaviour is described in the C# specification, unfortunately - I don't think the unboxing behaviour from "boxed int
" to "enum with an underlying type of int
" is described, as far as I can see, which is a sort of prerequisite to then including nullability in the mix.