2011-03-02 116 views
4

我有一大堆不同的枚舉,如...IEnumerable的擴展方法<Enum>?

public enum MyEnum 
{ 
    [Description("Army of One")] 
    one, 
    [Description("Dynamic Duo")] 
    two, 
    [Description("Three Amigo's")] 
    three, 
    [Description("Fantastic Four")] 
    four, 
    [Description("The Jackson Five")] 
    five 
} 

我寫的擴展方法對於任何枚舉得到Description屬性(如果有)。簡單的權利...

public static string GetDescription(this Enum currentEnum) 
{ 
    var fi = currentEnum.GetType().GetField(currentEnum.ToString()); 
    var da = (DescriptionAttribute)Attribute.GetCustomAttribute(fi, typeof(DescriptionAttribute)); 
    return da != null ? da.Description : currentEnum.ToString(); 
} 

我可以很簡單地使用它,它像一個魅力,像預期的返回描述或ToString()。

雖然這是問題。我希望能夠在MyEnum,YourEnum或SomeoneElsesEnum的IEnumerable上調用此方法。所以我簡單地寫了下面的擴展。

public static IEnumerable<string> GetDescriptions(this IEnumerable<Enum> enumCollection) 
{ 
    return enumCollection.ToList().ConvertAll(a => a.GetDescription()); 
} 

這是行不通的。它編譯罰款作爲一種方法,但使用它給出了以下錯誤:

Instance argument: cannot convert from 'System.Collections.Generic.IEnumerable<MyEnum>' to System.Collections.Generic.IEnumerable<System.Enum>' 

那麼,爲什麼呢? 我可以做這項工作嗎?

我在這一點上發現的唯一的答案是編寫通用科技推廣方法如下:

public static IEnumerable<string> GetDescriptions<T>(this List<T> myEnumList) where T : struct, IConvertible 
public static string GetDescription<T>(this T currentEnum) where T : struct, IConvertible 

必須有人對此有一個更好的答案,或者我爲什麼可以擴展一個枚舉的解釋但不是Enum的IEnumerable ... 任何人?

回答

7

.NET通用協方差只適用於參考類型。這裏,MyEnum是一個值類型,而System.Enum是一個引用類型(從枚舉類型轉換爲System.Enum是一個裝箱操作)。

因此,IEnumerable<MyEnum>不是IEnumerable<Enum>,因爲這會將每個枚舉項的表示從值類型更改爲引用類型;只允許表示保留轉換。您需要使用您發佈的通用方法技巧才能使其發揮作用。

0

從v4開始C#支持通用接口和委託的協方差和反方差。但不幸的是,這些* -variances僅適用於引用類型,它不適用於值類型,例如枚舉。

相關問題