0

I am trying to implement a generic extension method to get the underlying value of enum. Here is what i have achieved.This code seems to be working but I am not sure whether this is the correct way and works in all cases.

public enum Event
{
    Emails=60
}

public static class EnumExtension
{
    public static dynamic GetValue<T>(this T enumValue) where T:struct 
    {
        var enumTpe = Enum.GetUnderlyingType(typeof (T)) ;
        return Convert.ChangeType(enumValue, enumTpe);
    }
}

// later on in the code I am doing this

int eventId=Event.Emails.GetValue();

Please suggest.

Sameer
  • 3,124
  • 5
  • 30
  • 57

3 Answers3

4

It doesn't need to be this complicated.

Simply cast your Enum value to an int.

var eventId = (Int32)Event.Emails;
// eventId == 60

Also, you have a typo on your last line (Event.Email should read Event.Emails).

  • Until now I used to do the same. But thought of implementing a generic way to get the value without casting. Corrected the typo – Sameer Jul 24 '14 at 09:43
  • For what reason? On a plus, if you're just starting out with generics this is a good attempt. It's just unnecessary here unfortunately, casting it won't even present many performance problems that would be solved with any other approach. –  Jul 24 '14 at 09:44
  • I think this kind of functionality should have been provided by the platform itself.. getting underlying value without the need of casting by the developer. – Sameer Jul 24 '14 at 09:46
  • I have to disagree. Whether the developer needs to cast, or invoke the extension method, the developer still has to do something. That said, if you want it wrapping up in an extension method for some reason, refer to Luis Filipe's answer. –  Jul 24 '14 at 09:50
  • My bad, I was assuming string enums were possible. – Sameer Jul 24 '14 at 09:55
  • It is possible (in a sense), by using the `Description` attribute. For that, you'll need a cast again. Refer to http://stackoverflow.com/questions/2650080/how-to-get-c-sharp-enum-description-from-value –  Jul 24 '14 at 09:57
  • @Mokchhya - The platform does provide the ability to get the underlying value, via the [IConvertible interface](http://msdn.microsoft.com/en-us/library/system.iconvertible%28v=vs.110%29.aspx) which enums implement. But isn't casting easier? – dbc Jul 24 '14 at 10:26
1

Not all enums are integers. They can be s/bytes, u/shorts, u/ints and u/longs. Converting to an int can cause overflow exceptions, as can converting to an unsigned when a signed value is negative. If you insist on a generic method, this should work:

    static ulong ToUInt64<TEnum>(TEnum value) where TEnum : struct, IConvertible
    {
        // Silently convert the value to UInt64 from the other base 
        // types for enum without throwing an exception.
        // Required because the Convert functions do overflow checks.
        TypeCode typeCode = value.GetTypeCode();
        ulong result;

        switch (typeCode)
        {
            case TypeCode.SByte:
            case TypeCode.Int16:
            case TypeCode.Int32:
            case TypeCode.Int64:
                result = (UInt64)value.ToInt64(CultureInfo.InvariantCulture);
                break;

            case TypeCode.Byte:
            case TypeCode.UInt16:
            case TypeCode.UInt32:
            case TypeCode.UInt64:
                result = value.ToUInt64(CultureInfo.InvariantCulture);
                break;

            default:
                throw new InvalidOperationException();
        }
        return result;
    }

But really, isn't casting it directly without a generic helper just easier?

long value = (long)Event.Emails;

By the way, you can't do (int)value in a generic method. It won't compile, perhaps because the compiler doesn't have an enum constraint and doesn't know the enum size at compile time? The generic version must go through the IConvertible interface instead.

dbc
  • 104,963
  • 20
  • 228
  • 340
0

From my perspective i always use the explicit int cast directly. But if you'd like to provide an extension you can simply to this:

public static class EnumExtension
{
    public static int GetValue<T>(this T enumValue) where T:struct 
    {
       return (int)enumValue;
    }
}
Luis Filipe
  • 8,488
  • 7
  • 48
  • 76