tags:

views:

85

answers:

3

I'm looking to write a utility function that gets a integer from the database and returns a typed Enum to the application.

Here is what I tried to do (note I pass in a datareader and columnname instead of the int in my real function)...

    public static T GetEnum<T>(int enumAsInt)
    {
        Type enumType = typeof(T);

        Enum value = (Enum)Enum.ToObject(enumType, enumAsInt);
        if (Enum.IsDefined(enumType, value) == false)
        {
            throw new NotSupportedException("Unable to convert value from database to the type: " + enumType.ToString());
        }

        return (T)value;
    }

But it won't let me cast (T)value saying "Cannot convert type 'System.Enum' to 'T'.

Also I've read quite a bit of mixed reviews about using Enum.IsDefined. Performance wise it sounds very poor. How else can I guarentee a valid value?

Thanks!

+3  A: 

Like this:

return (T)(object)value;
SLaks
It would be better to initially declare `value` as an `object`.
João Angelo
Thanks that seems to compile. I don't understand the reason for the error then? Bonus points if you can explain why in the interest of learning:)
Justin
The compiler doesn't realize that `T` is a enum type. As far as it is aware, `T` might be `DateTime`. Therefore, you cannot cast directly from any type other than `object` to `T`.
SLaks
I did try to constrain T in the method signature with "where T : Enum". But the compiler tells me Constraint cannot be special class 'System.Enum'.
Justin
@Justin: [Yes; this is an annoying and unnecessary limitation](http://stackoverflow.com/questions/1331739/enum-type-constraints-in-c/1416660#1416660)
SLaks
+2  A: 

Change this:

Enum value = (Enum)Enum.ToObject(enumType, enumAsInt);

to this:

T value = (T)Enum.ToObject(enumType, enumAsInt);

and remove the cast :)

Porges
A: 

Can you put a constraint on the generic type to force it to derive from Enum? I can't remember if all enum types actually use Enum as a base class.

Don Kirkby
No it won't let me:) Constraint cannot be special class 'System.Enum'. Good idea though I thought the same thing.
Justin
You can't in C#. If you edit the resulting assembly, you can add it. See http://code.google.com/p/unconstrained-melody/
Porges