9

I have a list of Enums as an IEnumerable<T> and I need to loop on each item and get its description like this:

IEnumerable<T> values = (T[])Enum.GetValues(typeof(T));
foreach (Enum value in values)
{
    String mylist = Common.MyExtensions.getEnumDescription(value);
}

...

public static string getEnumDescription(Enum value)
{
    FieldInfo fi = value.GetType().GetField(value.ToString());

    DescriptionAttribute[] attributes =    (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);

    if (attributes != null && attributes.Length > 0)
    {
        return attributes[0].Description;
    }
    else
        return value.ToString();
}

This produces an error at the foreach section

cannot convert "T" to System.Enum.

Isn't IEnumerable a list of System.Enum in the first place? What sort of cast can do the trick?

4
  • Shouldn't Enum be T? Commented Nov 24, 2014 at 9:07
  • Maybe try without casting. Like this: var values = Enum.GetValues(typeof(T)); Commented Nov 24, 2014 at 9:07
  • Where is enum variable? Use that instead of T. Commented Nov 24, 2014 at 9:09
  • The collection returned from Enum.GetValues is not a collection of Enums but a collection of ints (most probably). Commented Nov 24, 2014 at 9:11

5 Answers 5

10

One way to do the cast is:

Enum enumValueError = (Enum)value;
//compiler error: Cannot convert type 'xxx' to 'System.Enum'
Enum enumValueNoError = value as Enum; 
//no error, but enumValueNoError will be null if value is not an Enum
Sign up to request clarification or add additional context in comments.

1 Comment

Alternatively (int)(object)value
4

Isn't IEnumerable a list of System.Enum in first place ? What sort of Cast can do the trick ?

Yes but compiler can't make sure this. T can be anything at runtime. In situations like this you usually use generic type constraints but where T : Enum is not valid, so what you can do is:

  1. Don't make your method generic, change the parameter type to Enum if you wanna work with Enums only
  2. Use where T : struct constraint to at least make sure T is a value type and check if the type is Enum inside of your method, if it's not throw an exception etc. (this is not recommended)

1 Comment

For your first solution: it would need some more work: Enum.GetValues(t) where t is a run-time Type instance, cannot be cast to Enum[]. For your second solution: that doesn't tell the OP how to get rid of the compile-time error about a conversion between T and Enum.
2

I guess your looking for something like this (changed the implementation a bit):

public enum Test
{
    [Description("This")]
    A,
    B,
    C,
    D
}

private IEnumerable<string> GetEnumDescription<T>()
{
    var type = typeof(T);

    if (!type.IsEnum) throw new ArgumentException("Only Enum types allowed");

    foreach (var value in Enum.GetValues(type).Cast<Enum>())
    {
        yield return getEnumDescription(value);
    }
}

public string getEnumDescription(Enum value)
{
    FieldInfo fi = value.GetType().GetField(value.ToString());

    DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);

    if (attributes != null && attributes.Length > 0)
    {
        return attributes[0].Description;
    }
    else
    {
        return value.ToString();
    }
}

And the call will look like:

var desc = GetEnumDescription<Test>(); // "This", "B", "C", "D"

Comments

0

Consider using the type T that you're already working with...

IEnumerable<T> values = (T[])Enum.GetValues(typeof(T));
foreach (T value in values)
{
    String mylist = Common.MyExtensions.getEnumDescription(value);
}

You will also have to make getEnumDesciption generic as well.

1 Comment

then the same error will occur at different place: getEnumDescription(value);
-1
foreach(var e in values)
{
    if(e is Enum)
    {
        Enum eAsEnum = (Enum)e;
        String mylist = Common.MyExtensions.getEnumDescription(eAsEnum);
    }
}

1 Comment

this will still give the same error at the cast Enum eAsEnum = (Enum)e;

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.