Enumerations are a simple and efficient way to deal with a set of values. The most common way to use an enumeration is to use its values separately. There are however times when we want to use a combination of the enumeration's values. In that case we can use bitwise operators. To make things easier, we can also use flags.

Enumeration

Let's start using a simple enumeration example. Enumerations are structs consisting of a set of values the type can be assigned. So let's use an enumeration of payment methods. Here's the enumeration.

public enumPaymentMethods

{

None = 0,

Cash = 1,

Cheque = 2,

CreditCard = 3

}

We can now use this enumeration to connect PaymentMethod values with their integer representation. For example

int creditCard = 3;

PaymentMethods creditCardMethod = (PaymentMethods)creditCard;

or

int creditCard = (int)PaymentMethods.CreditCard;

It is quite easy to switch between the enumeration and its numeric equivalent and use it anyway we want. Either to set the value to a select item or to store it in a database table. This method seems to be ok for let's say an e-shop where the customer chooses a product and selects a method to pay. However, that wouldn't work in case of a crm system where the customers wished to have more than one way of payment. For example, some client might wish to choose as payment method Cheque or CreditCard.

Bitwise Operators

In order to choose multiple values rather than a single one, we can use bitwise operators. In other words we can use an enumeration's binary value instead of the integer representation. This is called Flag Enumeration, even though using the Flag keyword is not mandatory.

For example, in the PaymentMethods enumeration each value's binary representation would be

Name Integer Binary

None 0 000

Cash 1 001

Cheque 2 010

CreditCard 3 011

Now, we could change the enumeration's values so they were all represented by powers of 2.

public enumPaymentMethodsAdvanced

{

None = 0,

Cash = 1,

Cheque = 2,

CreditCard = 4

}

In that case the previous table would look like

Name Integer Binary

None 0 000

Cash 1 001

Cheque 2 010

CreditCard 4 100

It's pretty clear that all we have said so far concerning PaymentMethods applies to PaymentMethodsAdvanced as well. Now let's see what choosing a combination of these values would look like.

One thing to keep in mind is how the 0 value works; the one called None in our example. Suppose we use HasFlag or the & operator (which actually end up in the same thing). Here's how things might get tricky.

This expression is always true regardless of the first value. So this is not the right way to tell if the value is None. To do so, we should do a direct comparison.

bool isNone = cashOrCheque == PaymentMethodsAdvanced.None;

One last thing: remember how we created our enumeration?

public enumPaymentMethodsAdvanced

{

None = 0,

Cash = 1,

Cheque= 2,

CreditCard = 4

}

The exact same thing can be done using bit shifting which can make things less complicated in case of long enumerations.

public enumPaymentMethodsAdvanced

{

None = 0,

Cash = 1 << 0,

Cheque= 1 << 1,

CreditCard = 1 << 2

}

Using Flags

It is a strange thing that many people tend to think that you need to use the Flags attribute in order to use bitwise operators. That is not true. We can use Flags however, to make things easier for us developers to debug or to display selected values.

To use Flags the only thing we need to do is to place the Flag keyword before the enumeration.

[Flags]

public enumPaymentMethodsFlags

{

None = 0,

Cash = 1,

Cheque = 2,

CreditCard = 4

}

So, if we had an enumeration with Flags as mentioned and another one without Flags, like this

Summary

We can use bitwise operators to combine multiple values from one single enumeration. The enumeration needs to contain powers of two as values. To compare such values we can use logical operators or the HasFlag method. In addition, we can use the Flags attribute to make debugging or parsing enumeration values easier.