[C#] Can my enums have friendly names?


Answers

You could use the Description attribute, as Yuriy suggested. The following extension method makes it easy to get the description for a given value of the enum :

    public static string GetDescription(this Enum value)
    {
        Type type = value.GetType();
        string name = Enum.GetName(type, value);
        if (name != null)
        {
            FieldInfo field = type.GetField(name);
            if (field != null)
            {
                DescriptionAttribute attr = 
                       Attribute.GetCustomAttribute(field, 
                         typeof(DescriptionAttribute)) as DescriptionAttribute;
                if (attr != null)
                {
                    return attr.Description;
                }
            }
        }
        return null;
    }

You can use it like that :

public enum MyEnum
{
    [Description("Description for Foo")]
    Foo,
    [Description("Description for Bar")]
    Bar
}

MyEnum x = MyEnum.Foo;
string description = x.GetDescription();
Question

This question already has an answer here:

I have the following enum

public enum myEnum
{
    ThisNameWorks, 
    This Name doesn't work
    Neither.does.this;
}

Is it not possible to have enums with "friendly names"?







public enum myEnum
{
         ThisNameWorks, 
         This_Name_can_be_used_instead,

}



This is a terrible idea, but it does work.

    public enum myEnum
{
    ThisNameWorks,
    ThisNameDoesntWork149141331,// This Name doesn't work
    NeitherDoesThis1849204824// Neither.does.this;
}

class Program
{
    private static unsafe void ChangeString(string original, string replacement)
    {
        if (original.Length < replacement.Length)
            throw new ArgumentException();

        fixed (char* pDst = original)
        fixed (char* pSrc = replacement)
        {
            // Update the length of the original string
            int* lenPtr = (int*)pDst;
            lenPtr[-1] = replacement.Length;

            // Copy the characters
            for (int i = 0; i < replacement.Length; i++)
                pDst[i] = pSrc[i];
        }
    }

    public static unsafe void Initialize()
    {
        ChangeString(myEnum.ThisNameDoesntWork149141331.ToString(), "This Name doesn't work");
        ChangeString(myEnum.NeitherDoesThis1849204824.ToString(), "Neither.does.this");
    }

    static void Main(string[] args)
    {
        Console.WriteLine(myEnum.ThisNameWorks);
        Console.WriteLine(myEnum.ThisNameDoesntWork149141331);
        Console.WriteLine(myEnum.NeitherDoesThis1849204824);

        Initialize();

        Console.WriteLine(myEnum.ThisNameWorks);
        Console.WriteLine(myEnum.ThisNameDoesntWork149141331);
        Console.WriteLine(myEnum.NeitherDoesThis1849204824);
    }

Requirements

  1. Your enum names must have the same number of characters or more than the string that you want to it to be.

  2. Your enum names shouldn't be repeated anywhere, just in case string interning messes things up

Why this is a bad idea (a few reasons)

  1. Your enum names become ugly beause of the requirements

  2. It relies on you calling the initialization method early enough

  3. Unsafe pointers

  4. If the internal format of string changes, e.g. if the length field is moved, you're screwed

  5. If Enum.ToString() is ever changed so that it returns only a copy, you're screwed

  6. Raymond Chen will complain about your use of undocumented features, and how it's your fault that the CLR team couldn't make an optimization to cut run time by 50%, during his next .NET week.




They follow the same naming rules as variable names. Therefore they should not contain spaces.

Also what you are suggesting would be very bad practice anyway.




One problem with this trick is that description attribute cannot be localized. I do like a technique by Sacha Barber where he creates his own version of Description attribute which would pick up values from the corresponding resource manager.

http://www.codeproject.com/KB/WPF/FriendlyEnums.aspx

Although the article is around a problem that's generally faced by WPF developers when binding to enums, you can jump directly to the part where he creates the LocalizableDescriptionAttribute.