02 November 2013

[Flag] attribute on enumeration explained

To understand new stuff it's better idea to start with an example. So let's not wait and go through below:

  1. Introduction to Enumeration marked with Flag attribute with example
  2. Solution: Enumeration with [Flag] attribute
  3. Important facts about enumeration marked with Flag attribute
  4. Working with Flag enumerations

Introduction to Enumeration marked with Flag attribute with example

Think you are working on class level design to build, a user interface to manage permission to users on the system. The available permission is View permission, Create permission, Update permission & Delete permission. A user having View permission can also have other permission as well. So users can have multiple permissions all at the same time.

To accommodate the above requirements we can think of a permission as enumeration having different defined values.

public enum PermissionType
{
   View,
   Create,
   Update,
   Delete
}

public class User
{
 public string Name {get; set;}
 public PermissionType Permission {get; set;}
}
The "User" class has a member of type "PermissionType" enum, to represent the permissions the user object has been granted.
User newUser = new User();
newUser.Permission = PermissionType.View;

Loking at the code, User class object can be assigned with only one permission at a time. Then how can User class object represent multiple permissions all at the same time? To achieve this, User class can maintain an array of PermissionType enumeration. That's not bad, but we have elegant solution to the problem.

Solution: Enumeration with [Flag] attribute

Let's modify the PermissionType enumeration by marking with Flag attribute

[Flag]
public enum PermissionType
{
   View =1,
   Create =2,
   Update =4,
   Delete =8
}

With Flag attribute on the enumeration we can assign multiple permission to User class object all at the same time. The individual Flag attributed enumeration permission types will be separated by pipe (|) symbol.

User newUser = new User();
newUser.Permission = PermissionType.View | PermissionType.Create 
                   | PermissionType.Update;
go top

Important facts about enumeration marked with Flag attribute

Flag Enumeration values binary representation and resultant values
  1. As you can see, the individual values View, Create, etc in the flagged enumeration have been assigned with 1, 2, 4, 16. These values are not random there are in the order.
  2. The first value View is nothing but 20 = 1 and second value Create = 21 = 2
  3. Similarly, the third value Update = 22 = 4 and Delete = 23 = 8
  4. That means, the enumeration marked with Flag attribute values should be 2X, where X being 0, 1, 2, 3, ..., N

Working with Flag enumerations

You can use the HasFlag() method to check whether given flagged attribute value has any of the defined values.
User newUser = new User();
newUser.Permission = PermissionType.View | PermissionType.Create 
                    | PermissionType.Update;
if(newUser.Permission.HasFlag(PermissionType.Create))
{
   // User has Create Permission
}