2011-03-31 88 views
26

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

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’ 找不到(使用指令或程序集 引用是否缺少 ?)”

+2

你为什么不告诉我们错误信息? – 2011-03-31 12:56:30

回答

48

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)); 
} 
+0

是的,这很好! – Alexandre 2011-03-31 13:13:35

+1

您可以通过编写'Cast '而不是'Cast '来稍微简化它,因为那样您就可以在第一个lambda表达式中将对象转换为int。 – 2011-03-31 13:14:00

+0

是的,你的权利:)好的提示:) Thx – 2011-03-31 13:15:27

4

你可以不使用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的回答以获得更多关于这方面的信息

+0

这不是我所期望的。我想使用扩展方法。 – Alexandre 2011-03-31 13:09:14

+0

显示您的使用情况和预期产出的代码示例。 (因为将它作为扩展方法调用似乎没有意义) – 2011-03-31 13:10:29

+1

@Alex Maslakov:扩展方法在这里并不合适,因为您正在根据静态可用的枚举数据构建字典(即它是枚举类型定义中的数据,而不是使用特定枚举值的属性)。扩展方法对一个类型的实例进行操作。 – 2011-03-31 13:15:10

12

那么,你试图使用变量类型Type作为泛型类型的参数。你不能用泛型来做到这一点,它们大约是编译时间类型。

你可以用反射来完成它,但是最好使它成为一个通用的方法。不幸的是,你不能将泛型类型参数限制为一个枚举,尽管我在Unconstrained Melody中有一些解决方法。

如果没有这样做,你可以使用一个struct类型的约束为一个通用的方法,这将是一个好的开始。

现在,下一个问题是,你正在试图获得一个Dictionary<int, string> - 但枚举的值不是int值。它们可能是可转换的int的值,但它们不会立即存在。你可以使用Convert.ToInt32来做到这一点,但你必须做

最后(目前)你会发现一个enum使用uintlong基础类型会发生什么?

1

这里是扩展方法我用转换枚举,唯一的区别是,我回来IEnumerbale>我的目的:

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

它也增加了空间的价值。

实施例:

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> 

虽然@保罗鲁安是正确的我已经发现这是一个非常有用的扩展方法。这不是一个完美的世界。

2

基于丹尼尔的解决方案

public static SelectList ToSelectList<TEnum>(this HtmlHelper h) where TEnum : struct 
{ 
return new SelectList(FortunaExtension.ToDictionary<TEnum>(), "Key", "Value"); 
}