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?

+2


source to share


4 answers


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!

+5


source


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.



+2


source


When you execute the command (TEnum) intEnumValue, the compiler doesn't know what class TEnum will be. Since int can be implicitly converted to certain classes, the compiler doesn't work. Casting for an object is valid and then TEnum is an object, so casting is also possible.

0


source


TEnum is an arbitrary type. Can you apply an int to a rectangle? To DateTime? The compiler doesn't know and unfortunately the spec says you can't add a constraint on it either.

0


source







All Articles