c# - IEnumerable<Enum> 的扩展方法?

标签 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
}

我为任何枚举编写了一个扩展方法来获取 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>'

这是为什么呢? 我可以完成这项工作吗?

此时我找到的唯一答案是为泛型 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

必须有人对此有更好的答案,或者解释为什么我可以扩展 Enum 而不是 Enum 的 IEnumerable ... 有人吗?

最佳答案

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

所以,一个 IEnumerable<MyEnum>不是 IEnumerable<Enum> ,因为这会将每个枚举项的表示从值类型更改为引用类型;只允许保留表示的转换。您需要使用您发布的通用方法技巧才能使其正常工作。

关于c# - IEnumerable<Enum> 的扩展方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5162389/

相关文章:

c# - 检测 WebBrowser 完成页面加载

java - 在 Kotlin 中解析列表的枚举

c# - TryParse 等效于 Convert with invariantculture

c# - 如何用空格表示枚举值?

java - 在枚举 Java 中使用数组

C#:使用别名 using 指令无法访问扩展方法

scala - 创建类型敏感函数而不更改父特征或案例类

ios - 从扩展文件中检测设备 (Swift)

c# - 如何计算 1 个特定类(class)的所有开放形式?

c# - "<<"在C#中代表什么?