C# enum friendly names

Tags: ,

If you develop using C# and the .Net ecosystem, chances are that you will need to use enums at a certain point. The enum keyword is used to declare an enumeration, a distinct type that consists of a set of named constants called the enumerator list. Enums are easy to use and especially useful if you have to work with some data data you don’t necessarily want to put in a database. Here’s a very short example of an enum:


public enum AvailabilityStatus
{

     Available, //0
     AvailableInOneMonth, //1
     AvailableInTwoMonths //2
}

I put 0, 1, 2 as comments just to point out that enums are by default of type int.
However, there might be a small challenge. As you can see we have the values “AvailableInOneMonth” and “AvailableInTwoMonths”. Most of the time you will want to display this values somewhere and “AvailableInOneMonth” is surely not something you want to display to users in this form. Instead, you would like to display “Available in 30 days” and “Available in 60 days”. And you can’t use spaces when you define the enum! So how to solve that?

Description attribute

To do that, we can use the “Description” attribute and decorate each enum value with the string representation that we want to display to end users. It would look something like that:


public enum AvailabilityStatus
    {
       [Description("Available")]
       Available,
       [Description("Available in 30 days")]
       AvailableInOneMonth,
       [Description("Available in 60 days")]
       AvailableInTwoMonths
    }

Still, this alone will not solve the entire issue and there are a few lines of code that we need to write. The main concept here is that we have to get the enum, look inside the field information, then look for the “Description” attribute and get the specified descriptions for the enum member that we need. It sounds complicated, but it really isn’t:


static void Main(string[] args)
{
       var availability = AvailabilityStatus.AvailableInOneMonth.ToString();
       FieldInfo fi = (new AvailabilityStatus()).GetType().GetField(availability);
       var attribute = (DescriptionAttribute)fi.GetCustomAttribute(typeof(DescriptionAttribute));
       availability = attribute.Description;
       Console.WriteLine(attribute.Description);
       Console.ReadLine();
}

This will display the needed enum value to the console, but using the form that we provided within the “Description” attribute. One of the ways to use this in a real application is to create an extension method containing the logic to extract the description (maybe in a static class?) and you could use it from anywhere in the application by providing the enum value:


public static class EnumFriendlyNames
{

    public static string GetDescription(Enum value)
      {
          string description = value.ToString();
          FieldInfo fi = value.GetType().GetField(value.ToString());
          var attribute = (DescriptionAttribute)fi.GetCustomAttribute(typeof(DescriptionAttribute));
          return attribute.Description;

      }

}

and….


user.Availability = EnumFriendlyNames.GetDescription(AvailabilityStatus.AvailableInOneMonth)

…where “user” is an object of the “User” class that has an AvailabilityStatus property.

That’s a very basic way to extract enum friendly names from enum members. Of course, things can get more complicated if we want, for example to display descriptions in different languages. In those cases we would need to create a custom attribute class and use that attribute instead of “Description”.

Update

I’m glad that I received some feedback and therefore I need to update this post. Even though using the Description attribute works for some scenarios, we should the Display attribute for this purposes. As I said earlier, it’s not only about code that works 🙂

The reason behind using Display attribute instead of Description is obvious from the official MSDN documentation. The Description attribute specifies a description for a property or event and it’s used mainly for documentation purposes inside Visual Studio.  It has only 3 properties and we would basically need to hard code the values that we want.

On the other hand, the Display attribute,  provides a general-purpose attribute that lets you specify localizable strings for types and members of entity partial classes. This means that we can use this attribute with resource files for localization, which can be really helpful. A practical use cases in an ASP.NET scenario is described in this blog post and I encourage you to read it if you’re not familiar with this topic (just like me :)).

The code for enum friendly names  remains almost the same. We have just to replace “DescriptionAttribute” with “DisplayAttribute”. The updated code would look like this:


class Program
{
        static void Main(string[] args)
     {
           var availability = AvailabilityStatus.AvailableInOneMonth.ToString();
           FieldInfo fi = (new AvailabilityStatus()).GetType().GetField(availability);
           var attribute = (DisplayAttribute)fi.GetCustomAttribute(typeof(DisplayAttribute));
           availability = attribute.Name;
           Console.WriteLine(availability);
           Console.ReadLine();
    }

        public enum AvailabilityStatus
    {
           Available,
           [Display(Name = "Available in 30 days")]
           AvailableInOneMonth,
           [Display(Name = "Available in 60 days")]
           AvailableInTwoMonths
    }

}

So, in order to have a maintainable and easy extendable code base it’s correct to use the Display attribute instead of the Description attribute to define and get enum friendly names.

 

Leave a Reply

Your email address will not be published. Required fields are marked *