In this post, I’ll show you how to create a custom attribute for enum values to assign extra information to an enum. In this case, we’ll be associating a user friendly display name.
In .NET, enums are basically a list of constant values. It’s a way to assign code friendly names to a group of values. For example, an order status:
enum OrderStatus
{
NewOrder = 1,
Processing = 2,
Shipped = 3
}
In the above example, the numeric values are optional, they will be assigned automatically if you don’t supply them.
What if you want to display the enum values in a drop down list, so that an admin can change the status of an order? One option is to loop through the enum, and display the code value ("NewOrder, "Processing", etc.). Another option is to have a "switch" statement or a "for" statement that allows you to hard code a user friendly value.
Another option is to create a custom attribute to add additional meta data:
public class EnumValueDataAttribute : Attribute
{
private string _name;
public string Name
{
get{ return _name; }
set{ _name = value; }
}
}
Now we can use the attribute to the enum I showed you previously:
enum OrderStatus
{
[EnumValueData(Name="New Order")]
NewOrder = 1,
[EnumValueData(Name="In Process")]
Processing = 2,
[EnumValueData(Name="Shipped")]
Shipped = 3
}
Now we can create a method that gets the data in a useful format:
public static Dictionary<int, string> GetListItems(Type enumType)
{
if (!enumType.IsEnum)
throw new ApplicationException("GetListItems does not support non-enum types");
Dictionary<int, string> list = new Dictionary<int, string>();
foreach(FieldInfo field in enumType.GetFields(BindingFlags.Static | BindingFlags.GetField | BindingFlags.Public))
{
int value;
string display;
value = (int)field.GetValue(null);
display = Enum.GetName(enumType, value);
foreach(Attribute currAttr in field.GetCustomAttributes(true))
{
EnumValueDataAttribute valueAttribute = currAttr as EnumValueDataAttribute;
if (valueAttribute != null)
display = valueAttribute.Name;
}
list.Add(value, display);
}
return list;
}
Notice that the method will also work even if the "EnumValueData" attribute is missing, so you don’t have to supply it for every value.
Based off of this code, you could easily create additional fields to associate with enum values. Basically what we’re doing is creating a simple database table in our code. You’ll have to decide if this is a good idea for your project.

There is a much simpler way of getting descriptive values from Enum values using framework attributes as I’ve described here:
http://www.moggoly.me.uk/blog/post/Enum-description-values.aspx
What about localizing these strings? Names are usually best kept in resource files for these reasons. What might be better is to add a value for a key in a resource file as well the default name value you have defined. If there is no resource file or no item for that key, then it can display the default name.
I prefere the much simpler approach of storing the strings in the resources, which solves localization at the same time
Or even better, use a TypeConverter so that it transparently works with databinding:
http://www.codeproject.com/KB/dotnet/DotNetEnumsNextLevel.aspx?msg=1604037#xx1604037xx
Why go through all the trouble?
Use reflection to populate the list …
Also for nice Spaced words write a string function that finds the upper case words and adds a space … like … “CoolComment” become “Cool Comment”. Why add the attributes, another hassle.
Also name your enums in a way that they come as nice words
Good post, I’ve been using enums most extensively to store the output ColumnNames of returned data.
RE: formatting
One option might be to use an underscore to seperate “words” and do a simple .Replace(“_”,” “) when the displayed version of the enum is required. That way upper/lower case doesn’t play into formatting.
Lots of great ideas. That’s why I love posting stuff like this!
Or use pseudo enums:
http://www.codeproject.com/KB/cs/DescriptiveEnum.aspx
An atttibute similar to this exists in the framework: System.Xml.Serialization.XmlEnumAttribute. To use it, it’s almost the same as your suggestion:
[System.SerializableAttribute()]
public enum TestEnum
{
value1,
[System.Xml.Serialization.XmlEnumAttribute("hi")]
value2
}
Then in code:
public static string ToStringUsingXmlEnumAttribute( Enum value )
{
if ( value == null ) throw new ArgumentNullException( “value” );
XmlEnumAttribute[ ] attribs = (XmlEnumAttribute[ ])value.GetType( ).GetField( value.ToString( ) ).GetCustomAttributes( typeof( XmlEnumAttribute ), true );
return ( attribs.Length > 0 ) ? attribs[ 0 ].Name : value.ToString( );
}
> I think logically.
Oh LOL, this entry is making me laugh my socks off.
Go on Son, reflect the mirror..
I’ve done this using extension methods you can check it out here.
http://www.objectreference.net/post/enum-to-friendly-string-extension-method.aspx
Greetings I recently finished reading through through your blog and also I’m very impressed. I really do have a couple concerns for you personally however. Think you’re thinking about doing a follow-up posting about this? Will you be going to keep bringing up-to-date also?
As an assembly language programmer I went for the simplest solution — a table, which to our kind often means array.
String arrays indexed into with the enumvalue gives you the description of the value.
It’s trivial to add to it. If you wanted to you could write it as a simple function or something. either way your program code size will increase as some constant + the number of enum entries you have.
k + n
space complexity is thus linear space: k + n = O(k + n) = O(n)
time complexity for a lookup is constant time: O(1)
but hey, that’s just me. We don’t get fancy for each statements and dictionaries and all that hat on the bare metal of microprocessors and microcontrollers. Heck, you gotta even specify what address in memory to store your crap at. So this was my gut instinct here.
I’d like to hear one good reason not to use it for high-level programming.