4

我有以下代码。我需要它来创建一个List具有KeyValuePair<string, string>指定枚举类型中每个枚举值的名称和值的 of。

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()会生成以下错误。

无法将类型“TEnum”转换为“int”

我只是想将枚举实例转换为整数。谁能告诉我为什么这行不通?

编辑:

我试过这个版本:

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

但这给了我错误:

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

4

2 回答 2

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

但是,这又存在一些问题:

如果枚举是 type longulong否则uint将返回不正确的值。ulong您可以通过强制转换为而不是来减少问题,int但这仍会为负枚举值返回无效值。

于 2013-05-16T06:48:36.667 回答
3

唯一安全的方法是使用为它创建的方法,而不需要现在的基类型!枚举类中的方法。甚至您也可以尝试使用该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();
于 2013-05-16T07:25:05.087 回答