Introduction
Have you ever wanted to add a more descriptive attribute to your enum
s? Well, here is one way. Let's take a very simple color based enumeration called MyColors
:
using System;
using System.ComponentModel;
using System.Reflection;
public enum MyColors{
White,
Red,
Green
}
Now, as you know, enumerations are represented by numbers (see the docs here).
If you want to associate text, we can do so by using System.ComponentModel.DescriptionAttribute
to do this.
using System;
using System.ComponentModel;
using System.Reflection;
public enum MyColors{
[Description("The Color of my skin")]
White,
[Description("Bulls like this color")]
Red,
[Description("The color of slime")]
Green
}
But just associating this attribute with our enum
doesn't help. We need a way to access that information too. By using reflection, we can get access to all the attributes for the enumeration. The code below describes a simple accessor that will retrieve the descriptions from each enumeration.
public static string GetDescription(object enumValue, string defDesc){
FieldInfo fi = enumValue.GetType().GetField(enumValue.ToString());
if (null != fi)
{
object[] attrs = fi.GetCustomAttributes(typeof(DescriptionAttribute), true);
if (attrs != null && attrs.Length > 0)
return ((DescriptionAttribute)attrs[0]).Description;
}
return defDesc;
}
And that is it. Now we can call...
GetDescription(MyColor.Green)
... and we will get back the text from the description. It is just that simple.
Just for fun, let's write a method to get back our enum
based on that string
. Note: This might be useful for most, but imagine that we define a new attribute called [AssociatedUriAttribute]
where we want to associate a URI with our enum
that is unique. This opens things up quite a bit. Note: This time we will embed this in a generics based class.
public class EnumUtils<T>
{
public static T FromDescription(string description){
Type t = typeof(T);
foreach (FieldInfo fi in t.GetFields())
{
object[] attrs =
fi.GetCustomAttributes(typeof(DescriptionAttribute), true);
if (attrs != null && attrs.Length > 0)
{
foreach (DescriptionAttribute attr in attrs)
{
if (attr.Description.Equals(description))
return (T)fi.GetValue(null);
}
}
}
return default(T);
}
In the end, we get a very simple class that looks like this:
using System;
using System.ComponentModel;
using System.Reflection;
public class EnumUtils<T>
{
public static string GetDescription(T enumValue, string defDesc){
FieldInfo fi = enumValue.GetType().GetField(enumValue.ToString());
if (null != fi)
{
object[] attrs = fi.GetCustomAttributes
(typeof(DescriptionAttribute), true);
if (attrs != null && attrs.Length > 0)
return ((DescriptionAttribute)attrs[0]).Description;
}
return defDesc;
}
public static string GetDescription(T enumValue)
{
return GetDescription(enumValue, string.Empty);
}
public static T FromDescription(string description){
Type t = typeof(T);
foreach (FieldInfo fi in t.GetFields())
{
object[] attrs = fi.GetCustomAttributes
(typeof(DescriptionAttribute), true);
if (attrs != null && attrs.Length > 0)
{
foreach (DescriptionAttribute attr in attrs)
{
if (attr.Description.Equals(description))
return (T)fi.GetValue(null);
}
}
}
return default(T);
}
}
History
- 17th April, 2006: Initial post