枚举到字典

时间:2011-03-31 12:55:35

标签: c# .net

我想实现扩展方法,它将枚举转换为字典。

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'   无法找到(你错过了吗?   使用指令或程序集   引用?)“

5 个答案:

答案 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来执行此操作,但您必须执行某些内容

最后(暂时)使用uintlong基础类型的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是正确的,但我发现这是一个非常有用的扩展方法。这不是一个完美的世界。