我想实现扩展方法,它将枚举转换为字典。
public static Dictionary<int, string> ToDictionary(this Enum @enum)
{
Type type1 = @enum.GetType();
return Enum.GetValues(type1).Cast<type1>()
//.OfType<typeof(@enum)>()
.ToDictionary(e => Enum.GetName(@enum.GetType(), e));
}
为什么不编译?
错误
“类型或命名空间名称'type1' 无法找到(你错过了吗? 使用指令或程序集 引用?)“
答案 0 :(得分:53)
Jon Skeet has written everything you need;)
但是在这里你的代码正在运行:
public static Dictionary<int, string> ToDictionary(this Enum @enum)
{
var type = @enum.GetType();
return Enum.GetValues(type).Cast<int>().ToDictionary(e => e, e => Enum.GetName(type, e));
}
答案 1 :(得分:13)
嗯,您正在尝试使用类型为Type
的变量作为泛型类型参数。你不能用泛型来做到这一点,这些泛型是关于编译时类型的。
你可以用反射来做,但最好将它作为通用方法。不幸的是,你不能将泛型类型参数限制为枚举,尽管我在Unconstrained Melody中有一些方法可以解决这个问题。
如果不这样做,你可以只使用一个struct
类型的约束作为一个良好的开端。
现在,下一个问题是您尝试获取Dictionary<int, string>
- 但枚举的值不是 int
值。它们可能可转换到int
值,但它们不会立即存在。您可以使用Convert.ToInt32
来执行此操作,但您必须执行某些内容。
最后(暂时)使用uint
或long
基础类型的enum会发生什么?
答案 2 :(得分:5)
您不能将type1用作通用参数,因为它是变量,而不是类型。
以下代码与您的代码显示的内容类似:
public static Dictionary<string, TEnum> ToDictionary<TEnum>()
where TEnum : struct
{
if (!typeof(TEnum).IsEnum)
throw new ArgumentException("Type must be an enumeration");
return Enum.GetValues(typeof(TEnum)).Cast<TEnum>().
ToDictionary(e => Enum.GetName(typeof(TEnum), e));
}
像这样使用:
ToDictionary<Colors>()
但我不确定,这是,你的期望是什么? 此外,它有一个问题:您可以传递任何结构,而不仅仅是枚举,这将导致运行时异常。有关详细信息,请参阅Jon的答案。
答案 3 :(得分:2)
基于丹尼尔的解决方案
public static SelectList ToSelectList<TEnum>(this HtmlHelper h) where TEnum : struct
{
return new SelectList(FortunaExtension.ToDictionary<TEnum>(), "Key", "Value");
}
答案 4 :(得分:1)
这是我用来转换枚举的扩展方法,唯一不同的是我正在返回IEnumerbale&gt;为了我的目的:
public static IEnumerable<KeyValuePair<int, string>> ToListOfKeyValuePairs<TEnum>(this TEnum enumeration) where TEnum : struct
{
return from TEnum e in Enum.GetValues(typeof(TEnum))
select new KeyValuePair<int, string>
(
(int)Enum.Parse(typeof(TEnum), e.ToString()),
Regex.Replace(e.ToString(), "[A-Z]", x => string.Concat(" ", x.Value[0])).Trim()
);
}
它还为Value添加了空格。
示例:
enum Province
{
BritishColumbia = 0,
Ontario = 1
}
用法:
<select>
<% foreach(var item in Province.BritishColumbia.ToListOfKeyValuePairs()){ %>
<option value="<%=item.Key %>"><%=item.Value %></option>
<% } %>
</select>
输出:
<select>
<option value="0">British Columbia</option>
<option value="1">Ontario</option>
</select>
虽然@Paul Ruane是正确的,但我发现这是一个非常有用的扩展方法。这不是一个完美的世界。