It's impossible to directly cast an int
to an unknown type, so the compiler won't allow (TEnum)intEnumValue
. The two casts you are doing now are actually subtly different: (object)
boxes the int
, while (TEnum)
casts the boxed int
to a TEnum
, which is statically allowed because an expression which is of static type object
might actually be of runtime type TEnum
.
There might also be some further subtlety: Normally, a boxed int
can only be unboxed to int
. I think I've explained why the conversion is allowed by the compiler, but not why it's also allowed by the runtime. Perhaps conversion to TEnum
is only allowed at runtime because TEnum
happens to be an enum that has int
as its base type? I think I remember reading that enums in the CLR are really just instances of their base type.
Edit: I confirmed my suspicion:
public static void Main()
{
int value = 1;
IntEnum i = ToEnum<IntEnum>(value); // Valid cast, runs fine.
ByteEnum b = ToEnum<ByteEnum>(value); // Invalid cast exception!
}
public enum ByteEnum : byte { }
public enum IntEnum : int { }
public static TEnum ToEnum<TEnum>(int value)
{
return (TEnum)(object)value;
}
So we can safely say that (TEnum)
on a boxed int
is only valid if TEnum
is in fact an int
under the covers!