The implementation of Flags using bitwise operators
Introduction:
Bitwise operators give you the ability to store multiple settings in a single primitive data type (e.g. an integer). This is useful when a single item has potentially more than one setting of the same type. For example, a message box could have an Ok button, a Cancel button, a Retry button or any combination of the above. By assigning a flag to each button, the complete combination of which buttons to show can be represented in a single primitive data type. Unlike all other articles i have seen in on this topic, i am not going to delve into exactly how this works (bit manipulation), but instead concentrate on how to implement the functionality in C#, VB.NET and then SQL. If you would like to understand how it all works, start
here.
Sections:
C# Implementation
VB.NET Implementation
TSQL Implementation
C# Implementation
Defining the Flags:
To start of with, declare an enum to list all the possible flags. Two things are important when declaring the enum. The first thing you will probably notice is the [Flags] attribute. This is necessary in order to indicate that the enumeration should be treated as a set of flags. The second important thing is assigning a value to each of the items in the enum. The first value should be 1, then just double the value for each consecutive item. The integer type in .NET can store up to 32 flags.
[Flags] private enum Buttons : int
{
···Ok = 1, Cancel = 2, Retry = 4, Help = 8
}
Tip: An "All" item could be added to the list of items in the enumeration as follows: All = Ok | Cancel | Retry | Help
Setting flags ON:
To set multiple flags, concatenate the desired flags using the bitwise OR symbol "|":
Buttons buttons;
buttons = Buttons.Ok | Buttons.Cancel;
Setting flags OFF:
buttons &= ~Buttons.Cancel;
Testing to see if a certain flag is set:
if ((buttons&Buttons.Ok)==Buttons.Ok)
···Console.WriteLine("Ok");
VB.NET Implementation
(This section in the same as the C# section, the examples are just in VB.)
Defining the Flags:
To start of with, declare an enum to list all the possible flags. Two things are important when declaring the enum. The first thing you will probably notice is the [Flags] attribute. This is necessary in order to indicate that the enumeration should be treated as a set of flags. The second important thing is assigning a value to each of the items in the enum. The first value should be 1, then just double the value for each consecutive item. The integer type in .NET can store up to 32 flags.
<Flags()> _
Private Enum Buttons As Integer
···Ok = 1
···Cancel = 2
···Retry = 4
···Help = 8
End Enum
Tip: An "All" item could be added to the list of items in the enumeration as follows: All = Ok And Cancel And Retry And Help
Setting flags ON:
To set multiple flags, concatenate the desired flags using the Or keyword:
Dim btns As Buttons
btns = Buttons.Ok Or Buttons.Cancel
Setting flags OFF:
btns = btns And Not Buttons.Cancel
Testing to see if a certain flag is set:
If (btns And Buttons.Ok) = Buttons.Ok Then
···Console.WriteLine("Ok")
End If
TSQL Implementation
Of course there are no enumeration constructs in TSQL, so the script required to implement flags is a bit rougher than in .NET, but it works just as well. This section anticipates that you would have already looked at one of the two sections above before you work through this one...
Setting flag 1 ON:
declare @MyFlags int
select @MyFlags = IsNull(@MyFlags, 0) | 1
Setting flag 1 OFF:
select @MyFlags = IsNull(@MyFlags, 0) ^ 1
Testing to see if flag 1 is set:
if (IsNull(@MyFlags, 0) & 1) <> 0
···select 'Yes'
else
···select 'No'
Finally...
That's all there is to it! I have attached source code / script samples, if you are unclear on anything, work through these samples and it should all make sense.
[01 May 08 : Fixed error in TSQL implementation, thank
Pepijn van de Kamp]