1

I have a simple class SelectItemOption that is used generically in dropdowns, lists, etc.

public class SelectItemOption
{
    public string Title { get; set; }
    public string ID { get; set; }
    public string Description { get; set; }
}

I want to create a method that populates a List<SelectItemOption> with values from an Enum. GetDisplayName() and GetDisplayDescription() get this info from the attributes.

I robbed some code from another SO answer to get the enum values into an enumerable.

    public static IEnumerable<T> EnumToList<T>()
        where T : struct
    {
        return Enum.GetValues(typeof(T)).Cast<T>();
    }

I am attempting to put it all together like this:

    public static List<SelectItemOption> EnumAsSelectItemOptions<T>()
        where T : struct
    {
        var optionsList = new List<SelectItemOption>();
        foreach (var option in EnumToList<T>())   //** headache here **
        {
            optionsList.Add(new SelectItemOption()
            {
                Title = option.GetDisplayName(),
                ID = option.ToString(),
                Description = option.GetDisplayDescription()
            });
        }
        return optionsList;
    }

The problem occurs when I try to iterate EnumToList.

No matter what I try, I can't seem to get the option variable to act like an Enum.

I've Tried...

If I use foreach (Enum option in EnumToList<T>()) I get "cannot convert type T to system.enum".

But if I use foreach (var option in EnumToList<T>()) my extension methods aren't recognised.

If I try to cast option as an Enum after the foreach statement I get "cannot implicitly convert type T to system.enum".

Aaaaggggghhhhh!

Community
  • 1
  • 1
Martin Hansen Lennox
  • 2,837
  • 2
  • 23
  • 64
  • That's because `option` isn't an `enum`, it's a `T : struct`. – Enigmativity Apr 24 '15 at 23:52
  • `EnumToList` will return an enumerable of `T`s. That's just how you've written it. The items you get aren't of type `Enum`, they're of whatever type of enum you're passing as the generic type argument to `EnumAsSelectItemOptions`. – Asad Saeeduddin Apr 24 '15 at 23:52
  • E.g. if you're calling `EnumAsSelectItemOptions()`, each `option` is of type `SelectItemOption`. – Asad Saeeduddin Apr 24 '15 at 23:54
  • This may be a daft question, but Is there not way to cast or convert the T so it's recognised as an Enum? I don't *think* it's possible to have an enum constraint instead of struct – Martin Hansen Lennox Apr 24 '15 at 23:55

1 Answers1

2

You can't constrain as Enum so option can only be a struct. However, you could try write your EnumAsSelectItemOptions method something like this:

public static List<SelectItemOption> EnumAsSelectItemOptions<T>()
    where T : struct
{
    var optionsList = new List<SelectItemOption>();
    foreach (var option in EnumToList<T>())   //** headache here **
    {
        optionsList.Add(new SelectItemOption()
        {
            Title = option is Enum
                ? (option as Enum).GetDisplayName()
                : option.ToString(),
            ID = option.ToString(),
            Description = option is Enum
                ? (option as Enum).GetDisplayDescription()
                : option.ToString(),
        });
    }
    return optionsList;
}
Enigmativity
  • 113,464
  • 11
  • 89
  • 172