I had an interesting discussion earlier regarding enums and how they work in .NET, and since I haven't I blogged in a while, I thought I'd post some thoughts.

Conceptually, an enumerated type is a type that has a set of values that can be (surprise surprise) enumerated.  This means, most significantly, that there is a finite number of possible values you can assign an enum.  That's a fairly abstract and, frankly, not very useful definition in the context of a programming language.

Let's move on to an (admittedly impractical) example.  The classic example of enum usage is as a primitive type identifier, such as:

public enum FruitKind {
    Banana, Cherry, Orange
}

Then, you write some methods that deal with these fruits:

public class FruitConsumer {
    ...
    public string GetColor(FruitKind kind) {

    switch (kind) {
        case FruitKind.Banana:
            return "Yellow";
        case FruitKind.Cherry:
            return "Red";
        case FruitKind.Orange:
            return "Orange";
        }
    }
}

But wait, the compiler is complaining that this code doesn't compile.  "'FruitConsumer.GetColor(FruitKind)': not all code paths return a value," it tells me.  But I covered every possible value of the enum, right?  What other code path is there?  The answer, of course, lies with something that is intimately familiar to those of us with C/C++ background:  enums are really integers under the hood.  FruitKinds are really ints under the hood, wrapped in a pretty box with a little language support for using the named values.

This dichotomy has some advantages.  For example, there are a lot of flag-type enums, where you can have any number of a series of values.  For example, the System.Reflection.BindingFlags type allows you to specify any number of binding options with the | (bitwise or) operator, and then the consumers of these can use & (bitwise and) to see if your flags fit.  This has good perf without overly obfuscating the meaning of those operations.

Additionally, you gain the convenience is the ability to switch on enums.  One other "advantage" many people will cite is the ability to do regular arithmetic on enums, though I have yet to see a convincing example of this being a good idea.

There are some downsides, too:  in the FruitKind example, you weren't certain that the code could never be called with a value other than those you defined.  Mostly, I am just bothered by the "weirdness" factor, that your enums are not guaranteed to be one of the values you set forth.  The OO solution is to use an abstract base class as the enum type with a private constructor, and have nested classes with singleton instances as your enum values (good post on the subject).  I think that's by far the best solution:  in return for arithmetic operations, you get methods; in return for switch/case, you can add a visitor hook.  Overall, it gives much greater flexibility (which, like most things, comes at the cost of some complexity).

One final note, which is completely off this train of thought, but it is the last thing that bugs me about enums in C#.  The literal zero is always implicitly convertible to any enum type.  Any integral value can be converted to any enum type explicitly, but only zero can be converted implicitly.  The reasoning, as I understand it, has to do with the fact that the memory that your enum instances are occupying is going to start out as zero anyway, so saying "FruitKind kind = 0" is the same as saying "FruitKind kind = new FruitKind()"; this is logical enough from a computer organization point of view.  At a high level, though, it doesn't mean I have to like it. ;)