Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Human readable strings for enum elements

4.43/5 (11 votes)
12 Aug 2010CPOL 21.4K  
Using enum really helps readability, but the values within the enum must understandably conform to the rules for variables names. This is fine until you need to display enum values to the user. This tip shows you how to associate and access a human readable string with each enum element.
I use a fair number of enum blocks, but I hate having matching switch statements to render them to a human readable string (or string arrays to do the same, particularly when my enum may have only six elements, with fixed values between 1 and hex 8000). So I worked this out to remove the problem and keep the descriptive text with the enum element definition.

This works by using reflection to access the DescriptionAttribute which can be applied to any control, and which can also be applied to any other object - including individual variables, should you so wish. (That might be overkill, but hey! It's your software!).


Declare these two static methods:
/// <summary>
/// Get description of a enum value
/// See DescriptionAttribute for enum element
/// </summary>
/// <remarks>
/// Returns the human readable string set as the DescriptionAttribute
/// for an enum element.
/// If the DescriptionAttribute has not been set, returns the enum element name
/// </remarks>
/// <example>
/// public enum MyEnum
///    {
///    [DescriptionAttribute("A Human readable string")]
///    AMachineReadableEnum,
///    }
/// ...
///    string s = MyEnum.AMachineReadableEnum.ToString();
///    s += " : " + GetDescription(MyEnum.AMachineReadableEnum);
///    MessageBox.Show(s);
///
/// would display "AMachineReadableEnum : A Human readable string"
/// </example>
/// <seealso cref="ValueOf<T>"/>
/// <param name="value">Enum element with human readable string</param>
/// <returns>Human readable string for enum element</returns>
public static string GetDescription(Enum value)
    {
    // Get information on the enum element
    FieldInfo fi = value.GetType().GetField(value.ToString());
    // Get description for elum element
    DescriptionAttribute[] attributes = (DescriptionAttribute[]) fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
    if (attributes.Length > 0)
        {
        // DescriptionAttribute exists - return that
        return attributes[0].Description;
        }
    // No Description set - return enum element name
    return value.ToString();
    }
/// <summary>
/// Get an enum element from its human readable string.
/// </summary>
/// <remarks>
/// Returns the enum element for a human readable string
/// If the DescriptionAttribute has not been set, throws an
/// ArgumentException
/// </remarks>
/// <example>
/// public enum MyEnum
///    {
///    [DescriptionAttribute("A Human readable string")]
///    AMachineReadableEnum,
///    }
/// ...
///    MyEnum me = ValueOf<MyEnum>("A Human readable string");
///    MyEnum me = MyEnum.AMachineReadableEnum;
///
/// would be equivelent
/// </example>
/// <exception cref="ArgumentException if description not found to match an enum element"
/// <seealso cref="GetDescription"/>
/// <typeparam name="T">Enum the element will belong to</typeparam>
/// <param name="description">Human readable string assocuiated with enum element</param>
/// <returns>Enum element</returns>
public static T ValueOf<T>(string description)
    {
    Type enumType = typeof(T);
    string[] names = Enum.GetNames(enumType);
    foreach (string name in names)
        {
        if (GetDescription((Enum) Enum.Parse(enumType, name)).Equals(description, StringComparison.InvariantCultureIgnoreCase))
            {
            // Found it!
            return (T) Enum.Parse(enumType, name);
            }
        }
    // No such description in this enum
    throw new ArgumentException("The string is not a description or value of the specified enum.");
    }


Now declare your enum with the DescriptionAttribute:
public enum MyEnum
    {
    [DescriptionAttribute("A Human readable string")]
    AMachineReadableEnum,
    [DescriptionAttribute("Another Human readable string")]
    ASecondMachineReadableEnum,
    }

And try it out:
private void ShowItWorking()
    {
    string s = "";
    s = GetDescription(MyEnum.AMachineReadableEnum);
    s += " : " + MyEnum.AMachineReadableEnum.ToString();
    s += " : " + ValueOf<MyEnum>("a human READABLE string");
    MyEnum me = ValueOf<MyEnum>("A HUMAN readable STRING");
    s += " : " + ((int) ).ToString();
    MessageBox.Show(s);
    }

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)