## Why is this an issue?

An enumeration can be decorated with the FlagsAttribute to indicate that it can be used as a bit field: a set of flags, that can be independently set and reset.

For example, the following definition of the day of the week:

    [Flags]
    enum Days
    {
        Monday = 1,    // 0b00000001
        Tuesday = 2,   // 0b00000010
        Wednesday = 4, // 0b00000100
        Thursday = 8,  // 0b00001000
        Friday = 16,   // 0b00010000
        Saturday = 32, // 0b00100000
        Sunday = 64    // 0b01000000
    }

allows to define special set of days, such as `WeekDays` and `Weekend` using the `|` operator:

    [Flags]
    enum Days
    {
        // ...
        None = 0,                                                    // 0b00000000
        Weekdays = Monday | Tuesday | Wednesday | Thursday | Friday, // 0b00011111
        Weekend = Saturday | Sunday,                                 // 0b01100000
        All = Weekdays | Weekend                                     // 0b01111111
    }

These can be used to write more expressive conditions, taking advantage of bitwise operators and Enum.HasFlag:

    var someDays = Days.Wednesday | Days.Weekend;  // 0b01100100
    someDays.HasFlag(Days.Wednesday);              // someDays contains Wednesday

    var mondayAndWednesday = Days.Monday | Days.Wednesday;
    someDays.HasFlag(mondayAndWednesday);          // someDays contains Monday and Wednesday
    someDays.HasFlag(Days.Monday) || someDays.HasFlag(Days.Wednesday); // someDays contains Monday or Wednesday
    someDays & Days.Weekend != Days.None;          // someDays overlaps with the weekend
    someDays & Days.Weekdays == Days.Weekdays;     // someDays is only made of weekdays

Consistent use of `None` in flag enumerations indicates that all flag values are cleared. The value 0 should not be used to indicate any other state since there is no way to check that the bit `0` is set.

    [Flags]
    enum Days
    {
        Monday = 0,    // 0 is used to indicate Monday
        Tuesday = 1,
        Wednesday = 2,
        Thursday = 4,
        Friday = 8,
        Saturday = 16,
        Sunday = 32,
        Weekdays = Monday | Tuesday | Wednesday | Thursday | Friday,
        Weekend = Saturday | Sunday,
        All = Weekdays | Weekend
    }

    var someDays = Days.Wednesday | Days.Thursday;
    someDays & Days.Tuesday == Days.Tuesday // False, because someDays doesn't contains Tuesday
    someDays & Days.Monday == Days.Monday   // True, even though someDays doesn't contains Monday!
    someDays.HasFlag(Days.Monday)           // Same issue as above

## How to fix it

### Code examples

#### Noncompliant code example

    [Flags]
    enum FruitType
    {
        Void = 0,        // Non-Compliant
        Banana = 1,
        Orange = 2,
        Strawberry = 4
    }

#### Compliant solution

    [Flags]
    enum FruitType
    {
        None = 0,        // Compliant
        Banana = 1,
        Orange = 2,
        Strawberry = 4
    }

## Resources

### Documentation

- FlagsAttribute
- Bit field
- Bitwise and shift operators (C# reference)
- Enum.HasFlag(Enum) Method

### Articles & blog posts

- Designing Flags Enumerations