Enums in .NET – part I

I guess all .NET developers have already used enums (aka enumerated types) in applications, right? if this is true, then you probably know everything there is to know about enums, right? If that is the case, then I’d say you’re can probably miss this and the next couple of posts. On the other hand, if you didn’t have the time to dig into things or if you’re unsure about one or two things, then this series will probably be worth a couple of minutes of your time 🙂

Lets start from the beginning, ok? What’s an enum? An enum is a type which defines several symbolic names/value pairs. Here’s a quick example good enough for getting started:

public enum Sizes { //int by default
    XSmall,//0
    Small, //1
    Medium, //2
    Large,//3
    XLarge//4
}

By default, all enum types use ints to store the values associated with symbolic names (this can be changed, as we’ll see in the next post). When you don’t initialize a symbolic name with a name explicitly, then the first name (XSmall) is associated with value 0, the second with the previous value + 1 (in this case, Small is associated with the value 1), and so on. After introducing an enum type, we can simply refer to its symbolic names. Here’s an example of this:

var size = Sizes.Small;

Many see enums as allowing us to mention a value by name (for instance, in the previous snippet, we could see Small as a “synonym” for 1). If that is the case, then are there any advantages in using enum types? The answer is yes, there are several:

  • they tend to improve the readability of your code (I believe that Sizes.Small confers meaning which 1 – its associated value – can’t);
  • they contribute to easing the maintenance of your code (if you’re using ints, what happens when you need to update 0 to 1?)
  • enums are *strongly* typed.

All of the previous reasons are important, but I believe the last one is *probably* the one that makes using enum a *must*. Being strongly typed means that the following code won’t compile:

public enum Colors {//also int
    Red, //0
    Green
}
static void DoSomethingWithSize(Sizes size) {
    //some code here
}
private static void Main( string[] args ) {
    Colors clr = Colors.Green;
    DoSomethingWithSize( clr );//oops: compile time error
}

Enum’s first class treatment gives us a lot of power. But there’s more. All enum types inherit from System.Enum (which inherits from System.ValueType). In pratice, this means that enum types are  value types. However, unlike other value types, you can’t add new methods to an enum directly (like you do when you create new struct). There’s a workaround for this, but the most common case is using inherited methods from the Enum base class (this class introduces several interesting methods which allow us to perform several utility operations over enum values – more about this in future posts).

Even though enum’s usage in C# is rather limited (you can define their symbolic names, values, “base types” and that’s it), it’s probably interesting to end this post by trying to understand how the C# compiler transforms that code into IL. Let’s give it a try, shall we? Let’s take a look at the IL generated for the Colors enum:

.class auto ansi sealed nested public Colors
            extends [mscorlib]System.Enum {
    .field public static literal valuetype ConsoleApplication1.Program/Colors Green = int32(1)
    .field public static literal valuetype ConsoleApplication1.Program/Colors Red = int32(0)
    .field public specialname rtspecialname int32 value__

}

As you probably can deduce, each symbolic name is transformed into a const field. In other words, it’s as if you’d written the following C# (btw, don’t try it! You’ll get a compile time error since the C# compiler won’t allow the direct use of the Enum type as a base type):

struct Colors:Enum {
    public const Int32 Red = 0;
    public const Int32 Green = 1;
}

As I’ve said, you can’t write this last snippet in C#. However, I believe that thinking about this implicit mapping between enum and this pseudocode makes it easy to understand why we can use the instance and static methods introduced by the System.Enum type, right? And I guess this is becoming a rather long post, so that’s all for now. Stay tuned for more on enums!

Advertisements

~ by Luis Abreu on June 6, 2011.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: