Search code examples
c#enumsbitwise-operatorsenumerationflags

Binary OR on [Flags] Enumeration Elements - Why is simple addition of Flags not allowed?


[Flags]
public enum EyeColors
{
    None = 0,
    Blue = 1 << 0,
    Cyan = 1 << 1,
    Brown = 1 << 2,
    Black = 1 << 3,
    Green = 1 << 4,
    Browngreen = 2 | 4
    // Browngreen = Brown | Green
}

While

Browngreen = 2 | 4
Browngreen = Brown | Green

does work

Browngreen = 6

does not. The evaluation of a test like

EyeColors.Browngreen == (EyeColors.Brown | EyeColors.Green);

evaluates to false in cases wheren Browngreen is set to 6.


This puzzles me. The way I understand the binary or is that the flagged bits get added so that:

0100 : 4
0010 : 2
0110 : 6

So why doesn't it work when I just set?

Browngreen = 6;

Solution

  • To combine flags, you need to use the | operator. Think it as binary : 10000 & 00100 will give 0 (None), but 10000 | 00100 will give 10100, hence 20, as you expect.

    Also, in your "All" case, the "None" flag has no meaning, I removed it.

    Here's a working example :

    [Flags]
    public enum EyeColors
    {
        None = 0,
        Blue = 1 << 0, // 1
        Cyan = 1 << 1, // 2
        Brown = 1 << 2, // 4
        Black = 1 << 3, // 8
        Green = 1 << 4, // 16
        Browngreen = Brown | Green,
        All = Blue | Green | Brown | Black | Cyan
    }
    
    void Main()
    {
        EyeColors eyeColors = EyeColors.Brown;
        Console.WriteLine(eyeColors + " (" + (int)eyeColors + ")");
    
        eyeColors = EyeColors.Brown & EyeColors.Green;
        Console.WriteLine(eyeColors + " (" + (int)eyeColors + ")"); // None
    
        eyeColors = EyeColors.Brown | EyeColors.Green;  
        Console.WriteLine(eyeColors + " (" + (int)eyeColors + ")"); // Brown green
    
        eyeColors = (EyeColors)20;
        Console.WriteLine(eyeColors + " (" + (int)eyeColors + ")"); // Brown green also
    
        eyeColors = EyeColors.All;
        Console.WriteLine(eyeColors + " (" + (int)eyeColors + ")");
    }