Many Questions: Switch On Enum

Just a quick one this week:

Why is it that you cannot use enum constants in a switch statement's cases without first casting them to type int?

Often you will want to use Enum constants as case labels in switch statements. Sometimes, the compiler will complain and require a cast to int on each case label. This will look something like this:

    enum Color { Red, Green, Blue };

  int i = ...;

    switch (i)

    {

    // cast required! Aarg!

    case (int)Color.Red: break;

    case (int)Color.Green: break;

    case (int)Color.Blue: break;

    }

The confusion stems from a subtle difference between C++ and C#. In C++, values of enum type are implicitly convertible to int. In C#, conversions between an enum type and its underlying type are explicit and require a cast. To maintain consistency, the requirement for the cast carries over into the use of enums in switch statements.

However, you can use expressions of enum type as case labels without a cast, but only in a type safe way. The rule is that the type of the expression being switched on, the ‘governing type’ of the switch statement in C# language spec terminology, must match the type of the expressions in the case labels.

For example:

    enum Color { Red, Green, Blue };

  Color c = ...;

    switch (c) // Governing type is ‘Color’ not ‘int’ so ...

    {

    // ... no cast required

    case Color.Red: break;

    case Color.Green: break;

    case Color.Blue: break;

    }

One of the design goals for enums in C# was to treat them as first class types that were truly distinct from their underlying type. This is one of the subtle ways that this decision manifests itself in the language.

Peter

C# Guy