I wanted to add text descriptions to my enum values; similar to overriding ToString on a class. This is what I came up with, using the beauty of generics:
A sample enum implementing my custom description attribute:
public enum MyEnum
{
[EnumDescription(“Funky chicken walks again!”)]
FunkyChicken = 0,
[EnumDescription(“Doctor?”)]
Doctor = 1
}
This next code block defines the custom attribute:
[AttributeUsage(AttributeTargets.Field)]
public class EnumDescriptionAttribute : Attribute
{
private string _text = “”;
/// <summary>
/// Text describing the enum value
/// </summary>
public string Text
{
get { return this._text; }
}
/// <summary>
/// Instantiates the EnumDescriptionAttribute object
/// </summary>
/// <param name=”text”>Description of the enum value</param>
public EnumDescriptionAttribute(string text)
{
_text = text;
}
}
Finally, a static method that prints the attribute from any enum, using generics:
static StringDictionary _enumDescriptions = new StringDictionary();
public static string GetEnumDescription<EnumType>(EnumType @enum)
{
Type enumType = @enum.GetType();
string key = enumType.ToString() + “___” + @enum.ToString();
if (_enumDescriptions[key] == null)
{
FieldInfo info = enumType.GetField(@enum.ToString());
if (info != null)
{
EnumDescriptionAttribute[] attributes = (EnumDescriptionAttribute[])info.GetCustomAttributes(typeof(EnumDescriptionAttribute), false);
if (attributes != null && attributes.Length > 0)
{
_enumDescriptions[key] = attributes[0].Text;
return _enumDescriptions[key];
}
}
_enumDescriptions[key] = @enum.ToString();
}
return _enumDescriptions[key];
}
For performance reasons, the StringDictionary is used to cache the values. Reflection tends to be expensive, so why not cache things? 🙂