Embed error in common extension
I modified the extension method Thorarin gave in the answer to this question to work on an int instead of a string:
public static TEnum ToEnum<TEnum>(this int intEnumValue, TEnum defaultValue)
{
if (!Enum.IsDefined(typeof(TEnum), intEnumValue))
return defaultValue;
return (TEnum)intEnumValue;
}
The compiler gives the error "Unable to convert type" int "to" TEnum "". on the last line.
If the line changes to this:
return (TEnum)(object)intEnumValue;
it compiles and works.
Why does the first object have to be put into an object?
source to share
Cannot be directly applied int
to unknown type, so the compiler will not resolve (TEnum)intEnumValue
. The two clicks you are doing now are actually subtly different: it (object)
fits into a square int
, but it (TEnum)
does a box of int
do TEnum
, which is statically resolved, because an expression that has a static type object
might actually be a runtime type TEnum
.
There may also be some further subtlety: usually the box int
can only be undoneint
. I think I explained why the conversion is allowed by the compiler, but not why it is also allowed by the runtime. Perhaps the conversion to TEnum
is only allowed at runtime because TEnum
is it an enum that has int
as its base type? I think I remember reading that enums in the CLR are just examples 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;
}
Thus, it is safe to say that (TEnum)
the box int
is only valid if TEnum
in fact is int
under the covers!
source to share
Eric Lippert has a blog post about this species here . Basically, there are several different types of "cast", and the transition from int to TEnum can be one of several. So the only safe way to do this is to insert an int into an object and then try to convert it to TEnum at runtime. You cannot go from int to TEnum, as what to do depends on what TEnum is and this is only known at runtime.
source to share