If you have some experience with programming languages in general, you must have heard about Enumerations (enums, for short) (And I'm not talking about dynamic collections, neither arrays. Enumerations are known at compile time, which means that they have constant values)
One advantage of using them is that you can't find yourself later on trying to fix a KeyNotFoundException or an IndexOutOfRangeException, since the compiler will give you an error (cleverly enough, I might say).
Also, you should know that there are various ways to create enumerations:
- static classes with constant members
- some languages offer the enum data type
So, (finally), what are Flags when talking about enums ? Well, while we regurarly use enums to express a single, constant value, there are cases when we need to have more constants in a single object.
Since this is a C# tutorial, the attribute I'm going to use is the System.FlagsAttribute. This sexy guy can be used on enums, and even though it doesn't do anything special, it tells the programmer "HEY, THIS ENUMERATION'S VALUES CAN BE MIXED UP".
Code:
[Flags] public enum DaysOfWeek { None = 0, Monday = 1, Tuesday = 2, Wednesday = 4, Thursday = 8, Friday = 16, Saturday = 32, Sunday = 64 }
Code:
if (this.WorkDays == DaysOfWeek.None) { }
Code:
if (this.WorkDays == 0) { }
Code:
class MyExampleProgram { [Flags] public enum DaysOfWeek { None = 0, Monday = 1, Tuesday = 2, Wednesday = 4, Thursday = 8, Friday = 16, Saturday = 32, Sunday = 64 } static void Main() { DaysOfWeek workDays = default (DaysOfWeek); // will be set to DaysOfWeek.None (= 0) Console.Write("Please write the day you would like to go to work this week (please be serious): "); int input = int.Parse(Console.ReadLine()); workDays = (DaysOfWeek) input; // notice the explicit cast Console.Write("You will go to work on {0}. Would you like to go to work on an other day too ? Press ENTER if your answer is no."); if (Console.ReadLine() == "") return; Console.Write("Please write the other day you would like to go to work this week (please be serious): "); int secondInput = int.Parse(Console.ReadLine()); workDays = workDays | (DaysOfWeek) secondInput; // notice we don't use the + operator, // insted we will use the Bitwise OR operator // the same line of code could have been written this way: // workDays |= (DaysOfWeek) secondInput; } }
What if we want to check if an enum object has a specific flag? BAM, the Bitwise AND operator (&):
Code:
if (workDays.HasFlag(DaysOfWeek.Monday)) { // you're not very lucky }
Code:
if (workDays & DaysOfWeek.Monday) { // you're not very lucky }
Code:
public class Enum { .... public bool HasFlag(Enum flag) { return this & flag != 0; } .... }
Here is where we meet the bitwise Negation (~) operator:
Code:
workDays = workDays & ~DaysOfWeek.Saturday; // ...
Code:
workDays &= ~DaysOfWeek.Saturday; // a bit shorter
So, let's review it:
- add a flag: the OR operator
- check for a flag: the AND operator
- remove a flag: the AND; Negation operator
If you have any other questions just post them here
PS: Yes, the values of the DaysOfWeek enum aren't correct here, since Monday | Tuesday = Wednesday, but I think you got the idea. When designing your enums' flags, make sure this won't happen if it isn't a logical combination.