DEV Community

Isaac Ayodeji Ikusika
Isaac Ayodeji Ikusika

Posted on • Edited on

Enum Flags in C#

TL;DR

  • Use the Flags attribute on your enum type
  • Use bit values as the enum representation because it allows you to use bitwise operators
  • Add up enums into a variable using the "|" operator
  • Use the HasFlags() method to determine whether one or more bit fields are set in an enumeration value.

You must have worked on a feature that involves switching between multiple options, and if you are a C# developer, you know you could easily do that with the enum type.

The enum type is a built-in value type which is the short form of the Enumeration type. Microsoft describes the enum as a type defined by a set of named constants of the underlying integral numeric type. This means that instead of having your options as numerical values, enums provide a way for you to use their representation.

A typical enum type is like this:

enum ColorTypicalEnum: int
{
   None = 0,
   Black = 1,
   Red = 2,
   Green = 4,
   Blue = 8
}
Enter fullscreen mode Exit fullscreen mode

The int type in front of the type tells the compiler the numerical type you want your enum represented as.

Flags in enum is an attribute that indicates that an enum type can be treated as a bit field. These bit fields are now grouped in a set of flags.
Here, you can represent the int in form of the enum fields as a bit. This makes working with the enum easier than the typical type.

[Flag]
enum ColorWithFlag: int
{
   None = 0,
   Black = 1,
   Red = 2,
   Green = 4,
   Blue = 8,
   ... //after some really, really long color listing
   ThisColorIsSoRare = 268435456
}
Enter fullscreen mode Exit fullscreen mode

The bit values here would be hard to comprehend and even easier to get wrong, e.g., how is ThisColorIsSoRare = 268435456? Good question, that is why you use bitwise operations instead.
So, we use the left shift operator:

[Flag]
enum ColorWithFlag: int
{
   None = 0,
   Black = 1,
   Red = 1 << 1, //2
   Green = 1 << 2, //4
   Blue = 1 << 3, //8
   ...
   ThisColorIsSoRare = 1 << 60, //268435456
   AllColors = int32.MaxValue
}
Enter fullscreen mode Exit fullscreen mode

Now, to the most interesting part of using flags. Because the Flag attribute allows you to use bitwise operations, you can easily do cool stuff like this:

// group all the primary colors (i.e. red, blue, and green) into one variable
var primaryColors = ColorWithFlag.Red | ColorWithFlag.Green | 
                    ColorWithFlag.Blue

//this sums the integer representation of the color in the `primaryColors` variable, so if you do

var primaryColorsIntegerValue = (int)primaryColors;
//you would get 14
Enter fullscreen mode Exit fullscreen mode

You can check if a color exists in the primary color variable using the HasFlag (which inner workings is a bitwise operation) method.

var isPrimaryColor = primaryColors.HasFlag(ColorWithFlag.Black);
//this returns false
Enter fullscreen mode Exit fullscreen mode

There is a massive chance you use Enums in your present or next project, so you be ready to use this knowledge of flags. It will make your code cleaner.

Please do check the provided links for a better understanding and examples.

Top comments (5)

Collapse
 
pbouillon profile image
Pierre Bouillon

Nice article about the usage of flags!

I may be wrong but I think that an enum is considered as an integer by default and that the type is inferred and therefore you do not need to explicitly indicate it:

enum Color { Red, Green, Blue }
// is the same as
enum Color: int { Red = 0, Green = 1, Blue = 2 }
Enter fullscreen mode Exit fullscreen mode

I also covered part of the subject a couple of days ago, if you want to check it out!

Collapse
 
ayodejii profile image
Isaac Ayodeji Ikusika

Nice spot, Pierre. You are right.
I indicated the integer values because I wanted to make readers see what the values would be when they are changed to bit values.

Collapse
 
nachmanberkowitz profile image
Nachman Berkowitz

I believe the Flag attribute just formats toString differently. Bitwise operators can be used on all Enums.

Collapse
 
stphnwlsh profile image
Stephen Walsh

Loved this. I may have missed this somewhere but can you now store a value in an object that represents multiple enum values that isn't a list?

Collapse
 
ayodejii profile image
Isaac Ayodeji Ikusika

thank you, Stephen. If I understand your question well enough,
The only value you can store in (or update) an object that represents (multiple) enum value(s) without an explicit conversion is an enum.
Something like this:

var myEnum =  ColorWithFlag.Red | ColorWithFlag.Green;
var myEnum |= ColorWithFlag.Blue; //add another enum value;
var myEnum = ColorWithFlag.Black; //update the whole enum with a new value entirely
Enter fullscreen mode Exit fullscreen mode

And if you do an explicit cast,

var myEnum =  (int)(ColorWithFlag.Red | ColorWithFlag.Green);
var myEnum = 20; //or any integer value you want.
Enter fullscreen mode Exit fullscreen mode