我有以下代码。我需要它来创建KeyValuePair<string, string>
的List
,其中包含指定枚举类型中每个枚举值的名称和值。
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' to 'int'
TEnum
是-每个约束-一个结构体。不能保证为enum。
但是,由于您在运行时强制该约束,因此您可以利用每个enum实现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
,则此操作将在运行时失败。
可以通过在转换到int
之前转换到dynamic
来克服这个问题:
((int)(dynamic)e).ToString()
然而,这又有一些问题:
如果枚举类型为long
、ulong
或uint
,则返回错误的值。您可以通过转换为ulong
而不是int
来减少问题,但对于负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();