score:1

In some sense, C# enums are similar to a object-oriented class hierarchy. If you declare enumeration Choice with alternatives One and Two, it is a bit similar to declaring a class hierarchy with base class Choice and two derived types (One : Choice and Two : Choice).

  • One difference is that enumerations are not extensible (if you need to add a case, you need to modify the declaration, while if you need to add a case to a class hierarchy, you simply define a new inherited type).

  • Second difference is that options of an enumeration cannot carry additional data - if you're declaring class hierarchy, you can store other fields in the One case (for example).

Without these two "limiations", you could consider using enumerations to represent entities in an application (in fact, functional languages have construct similar to these "more powerful" enumeration and use it for these kind of things).

However, since C# enumerations are very simple, they are mostly used to represent values independent of the specific domain, or values that are needed more generally in programming. For example:

enum TriState { True, False, Undecided }

This could be quite useful type, but it isn't directly related to any specific domain.

score:2

I use enums for database values that should never be created or altered by a user and if there is special logic based on the value. Currencies are not a good example unless you have every currency in your enumeration and accept that you will have to recompile your app should a new currency come along or one is deprecated. OrderStatus might be a good example if you have logic in your system based on the OrderStatus. Regardless, it should be noted that if you do create an enumeration to represent a database value, that the application must be recompiled should a new value in this table need to be created and thus this practice should be used with great caution.

In situations where I'm going to mimic a database value with an enumeration, I use the name of the enumerated value as the primary key of the table and as value passed to the foreign key. I.e., when I save to the database, I'm going to pass myEnumVal.ToString(). I have a couple of reasons for this. First, it requires that adding a value is more deliberate. If I were to use the numeric value as the primary key, there is an implication that I'm using a surrogate key and that additional values can easily be added. When other developers see a column using a name as the primary key, there is a higher chance that they'll think that the value is not arbitrary. Second, it makes database code significantly easier to read. You get queries like Where OrderStatus = 'Active' instead of Where OrderStatus = 1.


Related Articles