Combinable enumerations in C# .NET

You’ve probably encountered cases with combined enum values using the pipe character, i.e. the “bitwise or” operator ‘|’:

Size.Large | Size.ExtraLarge

Let’s see an example of how to create such an enum.

The enumeration is decorated with the Flags attribute like in the following example:

[Flags]
public enum SoftwarePositions
{
	Architect = 0
	, Developer = 1
	, Programmer = 2
	, FrontEnd = 4
	, BackEnd = 8
	, Database = 16
	, DomainModeller = 32
}

Enums that are meant to be combined are usually pluralised, like here: SoftwarePositions instead of SoftwarePosition, although this is not a syntactical requirement. We provide explicit numeric values starting with 0 followed by a series of 2^n, i.e. 2^0 = 1, 2^1 = 2, 2^2 = 4 etc. This has got to do with how enumerations are stored in memory. E.g. architect is 0 so it is represented as all 0’s in 8 bits:

00000000

Programmer has the value 2 so in binary it will become

00000010

So if you are a database developer then you can use the following combination:

var databaseDeveloper = SoftwarePositions.Database | SoftwarePositions.Developer;

…and for a front-end programmer you can use the following:

var frontEndProgrammer = SoftwarePositions.Programmer | SoftwarePositions.FrontEnd;

Setting multiple flags will switch them on in the correct places in memory, e.g.:

01001100

You can check if somebody works with databases in the following ways:

bool worksWithDatabases = (databaseDeveloper & SoftwarePositions.Database) != 0;
bool worksWithDatabasesAlt = databaseDeveloper.HasFlag(SoftwarePositions.Database);

…both will return true whereas the following will return false:

worksWithDatabases = frontEndProgrammer.HasFlag(SoftwarePositions.Database);

You can combine the combinations for do-it-all developers:

var doItAll = databaseDeveloper | frontEndProgrammer;

The Flags attribute will make sure that the following call results in a “nice” output:

Debug.WriteLine(doItAll);

…which prints

Developer, Programmer, FrontEnd, Database

Let’s say that the do-it-all developer stopped working with databases. We can remove that flag using the ^ operator:

var doSomeOfIt = doItAll ^ SoftwarePositions.Database;
Debug.WriteLine(doSomeOfIt);

This will print

Developer, Programmer, FrontEnd

We can just as easily put it back if the person works with databases again:

doSomeOfIt ^= SoftwarePositions.Database;
Debug.WriteLine(doSomeOfIt);

This will print

Developer, Programmer, FrontEnd, Database

You can remove a flag and not worry if the flag is present in the first place using a combination of the ~ and & operators:

var doItAllNoProgrammer = doItAll & (~SoftwarePositions.Programmer);

View all various C# language feature related posts here.

Advertisement

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Elliot Balynn's Blog

A directory of wonderful thoughts

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Once Upon a Camayoc

Bite-size insight on Cyber Security for the not too technical.

%d bloggers like this: