.NET tanker & tips

.Net, jQuery og andre nørdede emner

Don't let Tony Stark down - use enums!

November 04
by steffen 4. November 2018 16:56

Photo credit Marvel Studio

As a software developer you have many tools in our toolbox, that help create powerful and useful software applications. One of the most important concepts in software development is the principle of simplicity aka. the KISS principle. The more simple your code is, the easier it is to understand and to change, when a change request comes (and it will come sooner or later).

 

One of the most simple concepts that we have is the concept of flags. A flag is a marker that enable the program to recognize different program states and to decide how to proceed in the program flow. The most simple flag is the boolean, which has two states; true or false. But often the state of the program has more than two states and for this scenario the Enum solves the need perfectly.

 

An example of the use of enum, could be the software that defines which type of drivetrain a car has. A normal car is either front wheel drive, rear wheel drive or four wheel drive. This can be clearly represented with the following enum.

 

enum DriveTrain

{

    FrontWheelDrive,

    RearWheelDrive,

    FourWheelDrive

}

 

The drivetrain of a car can be clearly stated with the use of the DriveTrain enum.

 

This is all good and well, but as it turns out you work for Stark Industries and mr Stark has come up with a brand new design for a car, which can direct power to all four wheels independently. At any given time, depending on the situation, any combination of the four wheels can have power. It could be only the left frontwheel, the two right wheel or all four wheels. This requirement could be solved by adding a enum value for each of the wheel combinations, however this is not the most elegant solution.

 

Instead it is possible to use a neat little feature in C#, where it is possible to use the bitwise operators. First we will change our enum to reflect each wheel instead.

 

[Flags]

enum DriveTrain

{

    LeftFrontWheel = 1,

    RightFrontWheel = 2,

    LeftRearWheel = 4,

    RightRearWheel = 8

}

 

Let's start with looking at what we can do with this and we'll look into the nitty gritty stuff afterwards.

 

With this new enum we could do something like this:

DriveTrain wheelsWithPower = DriveTrain.LeftFrontWheel | DriveTrain.RightRearWheel;

 

A call to wheelsWithPower.ToString() returns "LeftFrontWheel, RightRearWheel" to indicate which of the enum values are set in the variable wheelsWithPower. If we have the need to query if a certain flag is set in the variabel we can do this with

 

bool powerToLeftRear = wheelsWithPower.HasFlag(DriveTrain.LeftRearWheel);

 

Very simple and concise!

 

Now let's dig in to some of the details. The most important thing to notice is the fact, that each enum value has a designated value (1, 2, 4 and 8). These number must be a power of 2. If this is not done the code will not work as expected. This has to do with the implementation of the HasFlags, which is a bitwise AND operation and hence each value must have it's own bit.

 

The second thing to notice is the [Flags] attribute. This is not needed for the HasFlags to work. This is only for getting nicer feedback while debugging. If the attribute was not added to the enum, a call to ToString() like above would return 9 instead of "LeftFrontWheel, RightRearWheel". Again this has to do with the underlying implementation, which rely on bit wize logic. The HasFlags works regardless of the Flags attribute.

 

Now mr. Stark can have his car, which alternates between powering each wheel independently and can go kick some bad guy ass.

Tags:

blog comments powered by Disqus