== Why is this an issue? An enumeration can be decorated with the https://learn.microsoft.com/en-us/dotnet/api/system.flagsattribute[FlagsAttribute] to indicate that it can be used as a https://en.wikipedia.org/wiki/Bit_field[bit field]: a set of flags, that can be independently set and reset. For example, the following definition of the day of the week: [source,csharp] ---- [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: [source,csharp] ---- [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 https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/bitwise-and-shift-operators[bitwise operators] and https://learn.microsoft.com/en-us/dotnet/api/system.enum.hasflag[Enum.HasFlag]: [source,csharp] ---- 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. [source,csharp] ---- [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 [source,csharp,diff-id=1,diff-type=noncompliant] ---- [Flags] enum FruitType { Void = 0, // Non-Compliant Banana = 1, Orange = 2, Strawberry = 4 } ---- ==== Compliant solution [source,csharp,diff-id=1,diff-type=compliant] ---- [Flags] enum FruitType { None = 0, // Compliant Banana = 1, Orange = 2, Strawberry = 4 } ---- == Resources === Documentation * https://learn.microsoft.com/en-us/dotnet/api/system.flagsattribute[FlagsAttribute] * https://en.wikipedia.org/wiki/Bit_field[Bit field] * https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/bitwise-and-shift-operators[Bitwise and shift operators (C# reference)] * https://learn.microsoft.com/en-us/dotnet/api/system.enum.hasflag[Enum.HasFlag(Enum) Method] === Articles & blog posts * https://learn.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/ms229062(v=vs.100)[Designing Flags Enumerations] include::../rspecator.adoc[]