Understanding EnumerationsBy Rachael Schoenbaum and Scott Mitchell
An enumeration is a special type in the .NET Framework that is comprised of a number of named constants. While you might not have created an enumeration type yourself, you have likely used enumerations many times in day-to-day programming. For example, each item in an ASP.NET DataGrid has an
ItemTypeproperty, which is of type
ListItemTypeis an enumeration with values like
Footer, and others. Too, if you've created files with the
System.IO.Fileclass you've used the
FileAccessenumerations; if you have worked with regular expressions, you've likely used the
When creating your own classes and components, enumerations can be used to make your code strongly typed, which makes the code more readable and less prone to errors. Creating and using enumerations is simple, so there's no reason not to use enumerations where applicable. This article looks at how to create enumeration types, how enumerations differ from constants, how to create enumerations whose members can be combined via bit-wise operations, and how to enumerate the members of an enumeration.
Creating an Enumeration Type
An enumeration can be declared with the following syntax:
EnumName is the name of the enumeration type, Type is the underlying value of the enumeration, and Named Constants is a set of names and optional values corresponding to the Type. All enumerations have some core, underlying, integral value type, such as a Byte, Integer, or Long. The default underlying type is Integer.
An example of creating an enumeration can be seen below:
Enumerations vs. Constants
A constant is single element whose value never changes, and is declared using the following syntax:
Where ConstantName is the constant's name, Type is the type, and Value is the constant's value, which can never be changed. The benefit of using constants is that they give a name to some "magic number," which improves code readability. Unfortunately, constants don't provide strong typing. For example, imagine we had the following constants defined:
Additionally, imagine that we have a method,
CreateMenuItem(Integer), that takes in an Integer
specifying the type of the menu item to create. This method might be called from the code like:
While this approach is clearly more readable that calling
the method allows any Integer to be passed in. That is, a call to
cause a compile-time error (although it would likely cause a runtime error of some sort).
An enumeration, on the other hand, is strongly typed. Rather than using constants, we could use an enumeration. The
CreateMenuItem() method, then, would expect an input parameter of type
MenuItemType, and would
be invoked using code like
With this approach, a compile-time error would be noted if we attempted to call
Enumerations Under the Covers
When compiling a project that includes enumerations, the enumeration is converted into a structure that turns each of the enumeration's named constants into an actual constant. That is, an enumeration like:
Would get turned into the following at compile-time:
Notice that this structure is derived from the
System.Enum class. The
contains the base functionality for all enumerations and provides methods for accessing the individual items of
an enumeration (as we'll see shortly).
Creating Enumerations Whose Members Can Be Joined via Bit-Wise Operations
What happens if your function or class needs to be passed more than one or more of your enumeration's values? For example, the
RegexOptionsclass spells out a number of regular expression options: if the regular expression should be compiled, whether it should ignore case, whether the regular expression should have the
$symbols match on a single line, or on multiple lines, and so on. Since a regular expression might need to be configured to support more than one of these options, the bit-wise OR operator can be used. For example, to create a regular expression object that is both multiline and compiled, you'd use:
Notice that in VB.NET the bit-wise OR operator is
OR; in C# it's
By default, an enumeration's members cannot be bit-wise ORed together. In order to create an enumeration that supports bit-wise operations you need to do two things:
- Mark the enumeration with the
- Assign the members of the enumerations values corresponding to the powers of 2
Here's a sample of how to declare an enumeration that can support bit-wise operations:
Notice that each enumeration member has an increasing power of 2 value: 1, 2, 4, and 8. To compute the next value in the series, simply multiple the last value by 2. The reason we need the numbers to be powers of 2 is because the way integers are represented by a computer. A thorough discussion of this is beyond the scope of this article.
Imagine we had a method called
MakeIdealHusband(Characteristics). This method could be called
MakeIdealHusband(Characteristics.Tall | Characteristics.Handsome), which would create a Tall and
Enumerating the Members of an Enumeration
There may be times where you need to loop through an enumeration and display either the names within the enumeration or the values. The
System.Enumclass contains a
GetNames(Type)method that returns a string array of the enumeration members. Here's an example of how to loop through your enumeration's names:
System.Enum class also contains a
Parse(Type, String) method that can be
used to get a strongly typed enumeration instance back based on a specified enumeration name. For example, to
get an enumeration instance of
Characteristics.Tall, we could use the following code:
Enumerations are good for lists of things that never or very rarely change. They are not good for lists that have frequent modifications since you would have to recompile your code every time something in your enumeration changed. Your enumeration must have values with one of the following data types: Byte, Integer, Long, or Short. If you can "translate" the underlying value of your enumeration to one of these data types then that list is a good candidate for an enumeration. If your underlying values are Char or String data types, these lists are not good candidates for enumerations.
Enumerations can make your coding a lot easier to read and understand by allowing you to refer to underlying lists of constants with logical names.
Rachael Schoenbaum is a developer specializing in ASP, ASP.NET, Visual Basic, SQL Server, XML, and related technologies. She consults for Lucidea and has been programming since 1999.