Expressing Flags using Enum

Alot of our time in coding are spent to reduce code duplication. There are even tools to count the number of duplicated lines like Simian, which some people use in their Continuous Integration build. With our constant effort to make world a better place, we come up with millions ways for not hard coding values into our code. Here is one of them

This post will discuss expressing flags using enum, using a common example of flagging: font styles. This post will also discuss what the FlagsAttribute is for.

The Problem

Let's say we want to keep the state of a ...say a television.
the value 0 as off
the value 1 as on.

After making this line of code, obviously one have to scream to the rest of the team, to use this convention. Until someone actually say ...
NO!!
the value 0 as off
the value 1 as idle
the value 2 as on

Using enum get rid of this hazard. Programmers does not need to know the value representation of a state.

It all works nice and well for mutually exclusive options. But what about in terms of a flagging situation? A common example is font styles. A piece of text can be bold and italic and/or underlined.

The Solution

[Flags]
public enum Style
{
	None = 0, 
	Bold = 1,
	Italic = 2,
	Underline = 4,
	BoldItalic = Bold | Italic
}

Please note a couple of things:

We explicitly assign none to 0. It's a good practice since literal constant 0 converts to any enum type (Bradbury C# Flags)

We also use base 2 numbers for the values to avoid bit collision. So what we really doing is relying on bitwise operation to implement flagging
I.e we store the values in:
0000
0010
0100
and so forth.
(If you're a soft eng or comp scientist and don't know what i mean...just try think a bit harder ;) - revise octal notation for filesystem using chmod)

It's possible to include common combination by using the bitwise OR operator (|).
Unlike plain English, we don't say Bold AND Italic. Because in a bit operation, bold AND italic means the subset of bold and italic, which is none.

You might think, by storing everything in base 2 numbers, why do we still need the FlagsAttribute? Good question!
The attribute specifically identifies that the enum can be used as a flag.

So for example, Bold and Underline will be stored as 101 in binary (5 in decimal. 1 + 4 = 5). In this case, we do not have an enum that represents 5.

StylStyle currentStyles = Style.Bold | Style.Underline;
Response.Write(orOperated.ToString());

If we were not using the FlagsAttribute, this line of code will produce '5' instead of 'Bold, Underline'. This is why the FlagsAttribute becomes important.

Common Use

Since we can have multiple enum values in a variable, we need to be able to check whether the variable contains a specific enum that you're looking for or not. This is how you would do it:

// Is it Italisized?
if ((currentStyles & Style.Italic) == Style.Italic) 
	Response.Write(orOperated.ToString());

Since, the operation above fully relying on bitwise operation, it's fully symmetric, transitive and reflexive.
You can also use other bitwise operation such as complement (~).

Reference
C# Flags
Using a Flag Enumeration with Bitwise Operations

Thanks to Xian the Code Monkeh for the heads up on this technique.