Smart Enumerations, Part II

I’ve made an update to my EnumerationHelpers code since the last release, which you can read about here. Previously, the only attribute that is supported for ‘get’ behavior is the Description attribute. This is all fine and good, but what about when you want to decorate your code with your own custom attributes, yet be able to get at them in a generic fashion?

Enter a brand new EnumerationHelpers method! This method is called GetCustomAttributes, and is written using generics for the best possible performance. Here’s an example of what it’s good for and how to use it:

enum Status

 [StatusColor("All is good", Color.Blue)]
 [StatusColor("Copacetic", Color.Pink)] Ok,
 [StatusColor("Uh oh..", Color.Orange)] Warning,
 [StatusColor("Holy Crap!", Color.Red)] Critical,
 [StatusColor("Rapture!!!", Color.Black)] Deadly


Status status = Status.Ok;

// Returns StatusColor Array containing the 'All is good' and 'Copacetic' StatusColor attributes.
StatusColor[] colorAttributes = EnumerationHelpers.GetCustomAttributes(status);

status = Status.Deadly;

// Returns StatusColor Array containing the 'Rapture!!!' attribute.
colorAttributes = EnumerationHelpers.GetCustomAttributes(status);

So, now tagging enumerations with information (and functionality) became even easier. There are very valid reasons to use enumerations to store application data, as opposed to say in a file or a database. The reason that I use enums often is that they are fast (since 99% of my enumerations are of type int under the covers) and they offer stronger typing than keeping values externally in data files or databases since the enum values are defined at compile time instead of run time (so less error handling code, too). They are also exceedingly simple to implement and very readable. There are obviously times when enumerations are not appropriate – typically when the data is volatile or when there is a large amount of data that needs to be maintained (the need for recompilation kills value in these situations).

Using this EnumerationHelpers class and some good programming, I’ve been able to implement finite state machines using a single enumeration and a single custom attribute. In this case the enumeration value would represent the current state, and the attribute would be used to hold state-transition information, including the next state. Well, anyway, the code is here, all zipped up for you. Everything is unit tested pretty well, so take a look at that to get a better idea of how to use it.

Describable, Smart Enumerations Helper Class (C# 2.0)

Update – Check out this article for the latest and greatest.

I’ve decided to post an EnumerationHelpers class written in C# 2.0. This class allows you to easily work with description tags on your enumeration values, and search them to pull the appropriate value out based on the description. This is great for times like when you want an enumeration to control a picklist but you don’t want to have to create a switch statement to match the displayed value with the enumeration value. In that respect, it also effectively isolates you from change (but, displayed values never change… right…). Here is an example of how to use it:

enum Status
 [Description("This is a new item")] New,
 [Description("This is an existing item")] Existing,
 [Description("This is an old item")] Old,

Status s = Status.New;

// Returns "This is a new item"
string strDescription = EnumerationHelpers.GetEnumDescription(s);

// Returns Status.Existing
s = EnumerationHelpers.GetEnumValueFromDescription("This is an existing item");

// Returns Status.Old
s = EnumerationHelpers.GetEnumValueFromDescription("Old");

// Returns "DescriptionUnavailable"
strDescription = EnumerationHelpers.GetEnumDescription(Status.DescriptionUnavailable);

As you can see, it becomes a fairly trivial task to implement describable enumerations. You can also see that it relies on the power of generics, and is type-safe. Feel free to take a look under the hood, and to use it for whatever needs you have. All I ask is that you leave in the copyright on the top of the code. Included in the package is a .csproj which includes the helper class and a set of NUnit tests that can help show you the ropes with the class. It’s available here!