C# enumerations are great; with one big drawback.
Every enumeration type has an underlying type, which can be any integral type except char. Which means that you can't associated a string value as the underlying type. This comes into play when you want to use the strongly typed features of an enumeration with a user friendly display value.
Say you want to bind the following enumeration to a dropdown:
1: public enum ItemStatus
2: { 3: Unknown = 0,
4: FailedValidation = 1,
5: SkuNotFound = 2,
6: ManufactureCodeNotExists = 3
7: }
You already know how that's going to turn out. Ugly.
To combat this issue we've used a variety of techniques in the past. Static strings off a class that mimic an enumeration, getter methods that return the enumeration name with spaces in the place where the name changes case, variants of the typesafe enum pattern, custom attributes... the works.
But homeboy over at moggoly.me.uk came up with the holy grail. It's so simple, you'll kick yourself because you didn't come up with it first.
By using an extension method off of Enum, in eight lines of code he's got this problem solved:
1: public static class Enum<T>
2: { 3: public static string Description(T value)
4: { 5: DescriptionAttribute[] da = (DescriptionAttribute[])(typeof(T).GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false));
6: return da.Length > 0 ? da[0].Description : value.ToString();
7: }
8: }
Now our previous example can be changed to:
1: public enum ItemStatus
2: { 3: [Description("Unknown")] 4: Unknown = 0,
5: [Description("Failed validation")] 6: FailedValidation,
7: [Description("Product not found")] 8: SKUNotFound,
9: [Description("Manufacturer code doesn't exist")] 10: ManufacturerCodeNotExists
11: }
And you can get the string value of the enum by calling:
1: ItemStatus myItemStatus = ItemStatus.FailedValidation;
2: string friendlyText = Enum<ItemStatus>.Description(myItemStatus);
Best part is, this works for all enumerations. If they don't specify the Description attribute, the enumeration's normal ToString() value is return.