Enum values as bit flags - using FlagsAttribute
The other day, I was using the RegexOptions
enum when creating a Regular Expression, and I thought it
would be useful to dedicate a blog entry to using
enumeration values as flags.
The following is a
poor example, but it should be illustrative enough.
Imagine
we have a Client class, and one of the Client properties
is ClientState. The ClientState enum can be defined as
follows:
public
enum
ClientStates
{
Ordinary,
HasDiscount,
IsSupplier,
IsBlackListed,
IsOverdrawn
}
As you can see - these options could be combined in
several ways. Rather then creating separate properties in
the Client class, we could enable a bitwise combination of
enumeration values by using the FlagsAttribute, when defining our enum type. See below.
[Flags]
public
enum
ClientStates
{
Ordinary,
HasDiscount,
IsSupplier,
IsBlackListed,
IsOverdrawn
}
This means we can now use the bitwise OR
operator to combine these enum values. For instance:
Client c =
new
Client();
c.ClientState =
(ClientStates.HasDiscount|ClientStates.IsSupplier|ClientStates.IsOverdrawn);
By setting the FlagsAttribute, the values for each
enum value now effectively become bitflag patterns that
look as follows if you see them in binary form:
00000000 0
00000001 1
00000010 2
00000100 4
00001000 16
00010000 32
00100000 64
01000000 128
As you can see, this bit pattern in our enum
values enables us to use the bitwise operator and combine
enum values. It is plain to see that all enum values
combined, using the bitwise OR, would result in 11111111.
So, how do we check what particular
ClientState values have been set? The key is the bitwise
AND operator. Let's take our existing Client object
'c'.
[Flags]
public
enum
ClientStates
{
Ordinary, // 0000
HasDiscount, // 0001
IsSupplier, // 0010
IsBlackListed, // 0100
IsOverdrawn // 1000
}
So for instance, if
we want to check c.ClientState
for ClientStates.HasDiscount
we can use the following expression:
(c.ClientState & ClientStates.HasDiscount) ==
ClientStates.HasDiscount
Assuming that c.ClientState contains
HasDiscount, IsSupplier and IsOverdrawn, the bit patterns
would look like:
c.ClientState: 1011
ClientStates.HasDiscount: 0001
(Logical AND): 0001
So by AND’ing the bit value to check for with
the combined bit pattern, we either get the same enum bit
pattern value back, or we get a bit pattern which only
contains zero’s.
Here’s a little helper method
you can use to check for particular ClientStates enum flag
values:
public
static
bool
ContainsClientState(ClientStates combined, ClientStates
checkagainst)
{
return
((combined & checkagainst)==checkagainst);
}
That’s it for now. Feel free to leave any comments.
Cheers!