正确实现泛型扩展方法获取枚举的基础值的方法

时间:2014-07-24 09:37:29

标签: c# .net enums

我正在尝试实现一个通用扩展方法来获取枚举的基础值。这就是我所取得的成果。这段代码似乎有效,但我不确定这是否正确,并适用于所有情况。

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();

请建议。

3 个答案:

答案 0 :(得分:4)

不需要这么复杂。

只需将您的枚举值转换为int

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

此外,您的最后一行也有拼写错误(Event.Email应该阅读Event.Emails)。

答案 1 :(得分:1)

并非所有枚举都是整数。它们可以是s / bytes,u / short,u / int和u / long。转换为int可能会导致溢出异常,因为当有符号值为负时,可以转换为unsigned。如果你坚持使用通用方法,这应该有效:

    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;
    }

但实际上,如果没有通用助手更容易直接投射它?

long value = (long)Event.Emails;

顺便说一下,你不能在通用方法中做(int)value。它不会编译,可能是因为编译器没有枚举约束并且在编译时不知道枚举大小?通用版本必须通过IConvertible接口。

答案 2 :(得分:0)

从我的角度来看,我总是直接使用显式int cast。但如果你想提供一个扩展,你可以简单地这样做:

public static class EnumExtension
{
    public static int GetValue<T>(this T enumValue) where T:struct 
    {
       return (int)enumValue;
    }
}