Francis Ducharme
Francis Ducharme

Reputation: 4987

Getting DisplayAttribute when itering on all enums of an assembly

I'm trying to iterate through all the enums contained in an assembly, and for each of them, build an object which I will return to a frontend.

I can retrieve the text value of a enum item, as well as its numeric value, but I'm trying to get its DisplayAttribute when there is one. (ie: [Display(Name = "Sales Admin")] instead of SalesAdmin)

Here's what I have so far

//represents an enum, that will be consumed by the frontend
public class DataEnumItem
{
    public string EnumName { get; set; }
    public Dictionary<string, int> Items { get; set; } = new Dictionary<string, int>();
}

private List<DataEnumItem> ReturnDataEnumItems<T>()
{
    List<DataEnumItem> results = new List<DataEnumItem>();
    var dataEnums = Assembly.GetAssembly(typeof(T)).GetTypes().Where(x => x.IsEnum && x.IsPublic);

    foreach (var e in dataEnums)
    {
        var values = Enum.GetValues(e);

        DataEnumItem item = new DataEnumItem();
        item.EnumName = e.Name;

        foreach (var value in values)
        {    
            item.Items.Add(value.ToString(), (int)value);
        }

        results.Add(item);
    }

    return results;
}

So far, that works, but like I said, I wish I could get the DisplayAttribute on each of the enum's item if there is one.

I have a method to do that, but only when I have a property that is strongly typed. For example:

enum MyEnum {
    [Display(Name = "First Choice")]
    firstChoice = 0
} 

public static string GetDisplay(this Enum enumValue)
{
    var displayAttr = GetAttribute<DisplayAttribute>(enumValue);
    if (displayAttr != null)
        return displayAttr.Name;
    else
        return "";
}

Then using it:

MyEnum x = MyEnum.firstChoice;
string display = x.GetDisplay();

Is there any to retrieve the display attribute when the enum value I have is not strongly typed (ie: retrieved via Enum.GetValues())

Upvotes: 1

Views: 55

Answers (1)

Guru Stron
Guru Stron

Reputation: 142243

You can cast to System.Enum and call your GetDisplay method:

foreach (var e in dataEnums)
{
    DataEnumItem item = new DataEnumItem();
    item.EnumName = e.Name;
    item.Items = Enum.GetValues(e)
        .Cast<Enum>()
        .Select(ev => (key: ev.GetDisplay(), value: (int)(object)ev))
        .ToDictionary(ev => ev.key, ev => ev.value);
    results.Add(item);
}

Or just substitute you dictionary addition with:

item.Items.Add(((Enum)value).GetDisplay(), (int)value)

Or, if previous options for some reason does not work for you:

e.GetField(value.ToString()).GetCustomAttributes<DisplayAttribute>()

Upvotes: 1

Related Questions