2

I am working on an AngularJS/Asp.Net MVC project and I have several Enums that have [Display(Name = "Value")] attributes on their values. I have an extension method that can extract the display name from these that works well enough:

public static string GetDisplayName(this Enum value)
{
    Type enumType = value.GetType();
    var enumValue = Enum.GetName(enumType, value);
    MemberInfo member = enumType.GetMember(enumValue)[0];

    var attrs = member.GetCustomAttributes(typeof(DisplayAttribute), false);
    var outString = ((DisplayAttribute)attrs[0]).Name;

    if (((DisplayAttribute)attrs[0]).ResourceType != null)
    {
        outString = ((DisplayAttribute)attrs[0]).GetName();
    }

    return outString;
}

Converting these Enums to Lists of the display name string values is easy enough:

//TODO: there *has* to be a way to do this with a generic or extension method
ViewBag.CurrencyTypes = Enum.GetValues(typeof(ProjectName.Web.Models.Common.CurrencyType)).Cast<ProjectName.Web.Models.Common.CurrencyType>().Select(v => v.GetDisplayName()).ToList();
ViewBag.PaymentTypes = Enum.GetValues(typeof(ProjectName.Web.Models.Common.PaymentType)).Cast<ProjectName.Web.Models.Common.PaymentType>().Select(v => v.GetDisplayName()).ToList();
ViewBag.OrgTypes = Enum.GetValues(typeof(ProjectName.Web.Models.Common.OrganizationType)).Cast<ProjectName.Web.Models.Common.OrganizationType>().Select(v => v.GetDisplayName()).ToList();
ViewBag.States = Enum.GetValues(typeof(ProjectName.Web.Models.Common.State)).Cast<ProjectName.Web.Models.Common.State>().Select(v => v.GetDisplayName()).ToList();

What I'm trying to figure out is, how do I create a common extension method that can create these lists? I tried using generics but adding where T : Enum throws an error.

Update: based on the type constriction of where T : struct, IConvertible from @Marcel's link, and the function @empi posted I have this static helper function:

public static List<string> GetDisplayList<T>() where T : struct, IConvertible
{
    if (!typeof(T).IsEnum)
    {
        throw new ArgumentException("T must be an enumerated type");
    }
    return Enum.GetValues(typeof(T)).Cast<Enum>().Select(v => v.GetDisplayName()).ToList();
}

Is there a way to make this an extension method?

Community
  • 1
  • 1
travis
  • 35,751
  • 21
  • 71
  • 94
  • Maybe this can get you started: http://stackoverflow.com/questions/79126/create-generic-method-constraining-t-to-an-enum – Marcel N. Aug 19 '14 at 19:50
  • Ah, interesting I'll give that a try and report back… – travis Aug 19 '14 at 19:52
  • 1
    Extension methods only work with instances, not on types. I mean, how would you even call an extension method on an enum type? I think that generic method is as good as it gets. Also relevant: http://stackoverflow.com/questions/2422113/extension-method-on-enumeration-not-instance-of-enumeration – Marcel N. Aug 19 '14 at 20:20

1 Answers1

2

Do you really need an extension method? A simple static method solves this problem:

public static List<string> CreateList<T>()
{
    return Enum.GetValues(typeof(T)).Cast<Enum>().Select(v => v.GetDisplayName()).ToList();
}

And when it comes to generic constraints you should look at Create Generic method constraining T to an Enum as stated in comments.

Community
  • 1
  • 1
empi
  • 15,755
  • 8
  • 62
  • 78
  • I don't, and I tried something similar but I was trying to `Cast` instead of `Cast` this may work, I'll try it… – travis Aug 19 '14 at 20:09