Tuesday, April 29, 2014

Enumeration types, switch statements and extra data and logic

An enum is basicly a collection of related choices or states. For example you can have an enum State { active, inactive }.
One of the main strenghts of an enum is that it can be used in a switch statement, thus eliminating the use of multiple if statements:
switch(state)
{
    case State.active: deactivate(); break;
    case State.inactive: activate(); break;
}

A switch statement only work with constant expressions, meaning code that is always compiled the same way, like numbers, chars and enums.

In most languages an enum is basicly nothing more than a single int. You can't specify that the State.active always has the color green, and the State.inactive the color red, or add methods to specify how comparison should work.

C#

In C# you can add some extra information to enums using attributes, and you can use extension methods and reflection to get some extra information, but even with these possibilities the enum still is quite dumb.

We can use an enumeration class to add extra information to our enum types (like described here: https://github.com/HeadspringLabs/Enumeration), but you can't use this enumeration class in a switch statement since the enumeration types are not constant expression.

C++

C++ has basicly the same problem. Since the newest version of C++ (C++11) typed enums are added, which makes the enum work like it does in C#, but it is still not possible to add logic or extra data to them.
An other nice addition to the newest C++ version is the constexpr keyword.
Using this keyword you can make your own types work in a switch statement, as long as they can convert to an int type:
struct State
{
    const int state;
    constexpr operator int() { return state; }
};
constexpr State active= { 1 };
switch(state)
{
    case active: ..
}
Unfortunatly  it is still not possible to do the following:
struct State
{
    static constexpr State Active = { };
};
So we still can't create the same type of enumeration classes as in C#, but we can come far with the following workaround I found:
struct StateType { /* the implementation of the type */ };
struct State
{
    static constexpr StateType Active = { };
    static constexpr StateType Inactive = { };
};

Conclusion

In conclusion, enums will not really change, but hopefully the creators/designers of programming languages will make the languages soon better to make it possible to use enumeration classes in switch statements like you can use enums.

No comments:

Post a Comment