Click here to Skip to main content
15,867,488 members
Articles / Programming Languages / C#
Tip/Trick

Human readable strings for enum elements

Rate me:
Please Sign up or sign in to vote.
4.43/5 (11 votes)
12 Aug 2010CPOL 20.1K   10   2
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)


Written By
CEO
Wales Wales
Born at an early age, he grew older. At the same time, his hair grew longer, and was tied up behind his head.
Has problems spelling the word "the".
Invented the portable cat-flap.
Currently, has not died yet. Or has he?

Comments and Discussions

 
GeneralReason for my vote of 3 I do something similar but use have ... Pin
SteveTheThread18-Aug-10 21:54
SteveTheThread18-Aug-10 21:54 
GeneralIt's been done Pin
PIEBALDconsult14-Aug-10 6:47
mvePIEBALDconsult14-Aug-10 6:47 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.