IEnumerable <enum>?</enum>的扩展方法

时间:2011-03-02 01:21:17

标签: c# enums extension-methods 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<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>'

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

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

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

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

2 个答案:

答案 0 :(得分:7)

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

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

答案 1 :(得分:0)

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