I have an enum like:
public enum Blah
{
RED = 2,
BLUE = 4,
GREEN = 8,
YELLOW = 16
}
Blah colors = Blah.RED | Blah.BLUE | Blah.YELLOW;
Thought this might be useful for other people that stumbled here like me.
Be careful how you handle any enum values that you might set to have a value == 0 (sometimes it can be helpful to have a Unknown or Idle state for an enum). It causes problems when relying on these bit manipulation operations.
Also when you have enum values that are combinations of other power of 2 values, e.g.
public enum Colour
{
None = 0, // default value
RED = 2,
BLUE = 4,
GREEN = 8,
YELLOW = 16,
Orange = 18 // Combined value of RED and YELLOW
}
In these cases an extension method such as this might come in handy:
public static Colour UnSet(this Colour states, Colour state)
{
if ((int)states == 0)
return states;
if (states == state)
return Colour.None;
return states & ~state;
}
And also the equivilent IsSet method that handles the combined values (albeit in a bit of a hacky way)
public static bool IsSet(this Colour states, Colour state)
{
// By default if not OR'd
if (states == state)
return true;
// Combined: One or more bits need to be set
if( state == Colour.Orange )
return 0 != (int)(states & state);
// Non-combined: all bits need to be set
return (states & state) == state;
}
What about xor(^)?
Given that the FLAG you are trying to remove is there, it will work.. if not, you will have to use an &.
public enum Colour
{
None = 0, // default value
RED = 2,
BLUE = 4,
GREEN = 8,
YELLOW = 16,
Orange = 18 // Combined value of RED and YELLOW
}
colors = (colors ^ Colour.RED) & colors;
To simplify the flag enum and make it may be better to read by avoiding multiples, we can use bit shifting. (From a good article Ending the Great Debate on Enum Flags)
[FLAG]
Enum Blah
{
RED = 1,
BLUE = 1 << 1,
GREEN = 1 << 2,
YELLOW = 1 << 3
}
and also to clear all bits
private static void ClearAllBits()
{
colors = colors & ~colors;
}
The other answers are correct, but to specifically remove blue from the above you would write:
colors &= ~Blah.BLUE;
You can use this:
colors &= ~Blah.RED;
And not
it...............................
Blah.RED | Blah.YELLOW ==
(Blah.RED | Blah.BLUE | Blah.YELLOW) & ~Blah.BLUE;