IEnumerable 的扩展方法?

我有一堆不同的枚举,比如……

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 } 

我为任何Enum编写了一个扩展方法,以获取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()按预期。

这是问题所在。 我希望能够在IEnumerable的MyEnum,YourEnum或SomeoneElsesEnum上调用它。 所以我简单地编写了以下扩展名。

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

这不起作用。 它编译精细的方法,但使用它会出现以下错误:

 Instance argument: cannot convert from 'System.Collections.Generic.IEnumerable' to System.Collections.Generic.IEnumerable' 

那么为什么呢? 我可以做这个吗?

我在这一点上找到的唯一答案是为genericsT编写扩展方法,如下所示:

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

有人必须有一个更好的答案,或解释为什么我可以扩展一个枚举但不是一个IEnumerable的枚举……任何人?

.NET通用协方差仅适用于引用类型。 这里, MyEnum是一个值类型, System.Enum是一个引用类型(从枚举类型到System.Enum是一个装箱操作)。

因此, IEnumerable不是IEnumerable ,因为这会将每个枚举项的表示从值类型更改为引用类型; 只允许表示保留转换。 您需要使用已发布的通用方法技巧来实现此function。

从v4开始,C#支持通用接口和委托的协方差和反方差。 但不幸的是,这些* – 方差仅适用于引用类型,它不适用于值类型,例如枚举。