Another Enum Gotcha

Steve is talking about the enum versioning problem. You know the one. It’s that annoying problem where you have an enum, say

enum Foo
{
    Bar  = 0,
    Bast = 1
}

Now, oftentimes, you will write a switch statement to deal with your different enumeration cases. (Incidentally, why isn’t their some sort of language structure to deal with this more naturally? Something a la polymorphism except for method dispatch based on an enumeration value. Switch statements suck.)

switch (enumValue)
{
    case Foo.Bar:
        // Do Foo stuff.
        break;
    
    case Foo.Bast:
        // Do Bast stuff.
        break;
}

Now, if you add a new enumeration value, your switch statement could break and do things you wouldn’t expect. Steve says you should always put a default handler in there, just in case. I agree, even if your default handler is to throw an exception or do a Debug.Fail().

There is one more case you need to be aware of, though. In .NET, it’s possible to cast an arbitrary value to your enumeration type and get around the type checking completely. Take the following case.

Foo enumValue = (Foo)42;

switch (enumValue)
{
    case Foo.Bar:
        // Do Foo stuff.
        break;
    
    case Foo.Bast:
        // Do Bast stuff.
        break;
}

This code is completely valid, and the enumValue will match neither the Bar case nor the Bast case. When would you ever encounter a case like this? (Pun intended.) I can’t really think of any off the top of my head, but writing secure and robust code means taking into account situations that should never occur. Incidentally, you can use the Enum.IsValue() method to determine if the value is defined by the enumeration or not.