Update and Extend an enum C#

Viewed 1375

I am attempting the below Question, but can not seem to figure out how to extend the enum:

Question:

Each account on a website has a set of access flags that represent a users access.

Update and extend the enum so that it contains three new access flags:

  • A Writer access flag that is made up of the Submit and Modify flags.
  • An Editor access flag that is made up of the Delete, Publish and Comment flags.
  • An Owner access that is made up of the Writer and Editor flags.

For example, the code below should print "False" as the Writer flag does not contain the Delete flag.

Console.WriteLine(Access.Writer.HasFlag(Access.Delete))

using System;

public class Account
{
   [Flags]
   public enum Access
   {
       Delete,
       Publish,
       Submit,
       Comment,
       Modify
   }

  public static void Main(string[] args)
  {       
      //Console.WriteLine(Access.Writer.HasFlag(Access.Delete)); //Should print: "False"
  }
}
1 Answers

You can do this by giving each flag of your enum a value that, if represented in the binary system, consists of only zeroes and a 1.

[Flags]
public enum Access
{
    // Simple flags
    Delete = 1,  // 00001
    Publish = 2, // 00010
    Submit = 4,  // 00100
    Comment = 8, // 01000
    Modify = 16, // 10000

    // Combined flags
    Editor = 11, // 01011
    Writer = 20, // 10100
    Owner = 31   // 11111
}

This way, writer will have both the submit and modify flag, but not the delete flag.

Why does this work?

The HasFlag method basically does a bitwise AND operation. So when you check whether delete is in the editor flag, it does this. Only if both bits are 1, the resulting bit will also be 1, otherwise 0.

00001
01011
----- & 
00001 

Check whether delete is in writer:

00001
10100
----- & 
00000

If the result is the same as the flag you're passing as a parameter, that means the flag is included!

More literal

You can define the numbers as binary literals as well. That way it is easier to see at a glance what's what.

[Flags]
public enum Access
{
    // Simple flags
    Delete =  0b00001,
    Publish = 0b00010,
    Submit =  0b00100,
    Comment = 0b01000,
    Modify =  0b10000,

    // Combined flags
    Editor =  Delete | Publish | Comment,
    Writer =  Submit | Modify,
    Owner =   Editor | Writer
}

or, as I like to write it

[Flags]
public enum Access
{
    // Simple flags
    Delete =  1,
    Publish = 1 << 1,
    Submit =  1 << 2,
    Comment = 1 << 3,
    Modify =  1 << 4,

    // Combined flags
    Editor =  Delete | Publish | Comment,
    Writer =  Submit | Modify,
    Owner =   Editor | Writer
}
Related