8

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"
  }
}
8
  • 3
    You can't. Just add more values to your original enum Commented Jan 14, 2021 at 22:34
  • Are you asking about extending it because it's compiled into something you don't control?
    – Caius Jard
    Commented Jan 14, 2021 at 22:35
  • I have added a link to the full question I am attempting - Perhaps this could provide more context ? I have just tried simplifying to in my question.
    – AxleWack
    Commented Jan 14, 2021 at 22:38
  • 1
    We don't have access to that link -- it gives an error.
    – Hogan
    Commented Jan 14, 2021 at 22:39
  • 2
    Even if we could access it, all relevant information should be in the post, not linked from external sites. Posts need to be immune to being invalidated when the external content has been removed (or is inaccessible as it is now). Commented Jan 14, 2021 at 22:40

1 Answer 1

15

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
}
0

Not the answer you're looking for? Browse other questions tagged or ask your own question.