Extension methods for IEnumerable <Enum>?

I have many different listings, such as ...

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 } 

I wrote an extension method for any Enum to get the Description attribute, if any. Simple enough ...

 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(); } 

I can use it very simply and works like a charm, returning a description or ToString (), as expected.

Here is the problem. I would like to be able to call this on IEnumerable from MyEnum, YourEnum or SomeoneElsesEnum. So I wrote the following extension as easy.

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

This does not work. It compiles as a method, but with it, the following error appears:

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

So why is that? Can I do this job?

The only answer I found at this stage is to write extension methods for general T as follows:

 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 

Someone should have a better answer for this or an explanation of why I can extend Enum, but not IEnumerable from Enum ... Anyone?

+4
source share
2 answers

General .NET covariance only works for reference types. Here MyEnum is the value type, and System.Enum is the reference type (discarding from the enumeration type to System.Enum is the boxing operation).

So, IEnumerable<MyEnum> not IEnumerable<Enum> , as this will change the representation of each enumerated element from a value type to a reference type; only conversions preserving the view are allowed. You should use the general trick of the method you posted to make this work.

+7
source

Starting with v4, C # supports codimension and contradiction for common interfaces and delegates. But, unfortunately, these * -variances only work for reference types; this does not work for value types such as enumerations.

0
source

Source: https://habr.com/ru/post/1341911/


All Articles