无法将枚举转换为Int

时间:2013-05-16 06:47:16

标签: c# reflection enums

我有以下代码。我需要它来创建List KeyValuePair<string, string> public static List<KeyValuePair<string, string>> GetEnumList<TEnum>() where TEnum : struct { if (!typeof(TEnum).IsEnum) throw new ArgumentException("Type must be an enumeration"); List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>(); foreach (TEnum e in Enum.GetValues(typeof(TEnum))) list.Add(new KeyValuePair<string, string>(e.ToString(), ((int)e).ToString())); return list; } ,其中包含指定枚举类型中每个枚举值的名称和值。

((int)e).ToString()

但是,表达式enum Fruit : short { Apple, Banana, Orange, Pear, Plum, } void Main() { foreach (var x in EnumHelper.GetEnumList<Fruit>()) Console.WriteLine("{0}={1}", x.Value, x.Key); } public static List<KeyValuePair<string, string>> GetEnumList<TEnum>() where TEnum : struct { if (!typeof(TEnum).IsEnum) throw new ArgumentException("Type must be an enumeration"); List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>(); foreach (TEnum e in Enum.GetValues(typeof(TEnum))) { list.Add(new KeyValuePair<string, string>(e.ToString(), ((int)(dynamic)e).ToString())); } return list; } 会生成以下错误。

  

无法将'TEnum'类型转换为'int'

我只是想将枚举实例强制转换为整数。谁能告诉我为什么这不起作用?

修改

我试过这个版本:

{{1}}

但这给了我错误:

  

无法将类型'System.Enum'转换为'int'

2 个答案:

答案 0 :(得分:9)

TEnum是 - 每个约束 - 一个结构。它不能保证是一个枚举。

但是,因为您在运行时强制执行该约束,所以您可以利用每个枚举实现IConvertible的事实:

foreach (IConvertible e in Enum.GetValues(typeof(TEnum)))
{
    list.Add(new KeyValuePair<string, string>(
        e.ToString(),
        e.ToType(
            Enum.GetUnderlyingType(typeof(TEnum)),
            CultureInfo.CurrentCulture).ToString()));
}

其他都有缺点的方法是:

您可以先转为object,然后转为int

请注意,如果枚举的基础类型不是int,则会在运行时失败。

这可以通过在转换为dynamic之前转换为int来克服:

((int)(dynamic)e).ToString()

然而,这又有一些问题:

如果枚举类型为longulonguint,则会返回错误的值。您可以通过转换为ulong代替int来减少此问题,但仍会返回负枚举值的无效值。

答案 1 :(得分:3)

在没有基本类型的情况下,唯一安全的方法是使用为其创建的方法! Enum类中的方法。即使您可以尝试使用IConvertable界面。

// Get underlying type, like int, ulong, etc.
Type underlyingType = Enum.GetUnderlyingType(typeof(T); 
// Convert the enum to that type.
object underlyingValue = e.ToType(underlyingType, null);
// Convert that value to string. 
string s = underlyingValue.ToString(); 

或简而言之:

string s = e.ToType(Enum.GetUnderlyingType(typeof(T)), null).ToString();

您可以在代码中实现它:

public static List<KeyValuePair<string, string>> GetEnumList<TEnum>() 
          where TEnum : struct, IConvertible
{
    if (!typeof(TEnum).IsEnum)
        throw new ArgumentException("Type must be an enumeration");
    List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>();
    foreach (TEnum e in Enum.GetValues(typeof(TEnum)))
    {
        list.Add(new KeyValuePair<string, string>
        (
            e.ToString(), 
            e.ToType(Enum.GetUnderlyingType(typeof(TEnum)), null).ToString()
        ));
    }
    return list;
}

如果您不想使用IConvertable,请尝试使用Convert类:

string s = Convert.ChangeType(e, Enum.GetUnderlyingType(typeof(TEnum))).ToString();