2011-03-31 117 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"); 
}