Bit flags provide a compact way to represent multiple on/off settings using individual bits within a single integer value. In C#, this pattern is commonly implemented using enumerations decorated with the [Flags] attribute.
Implementing Bit Flags with Enums
- Determine how many distinct flags are needed and choose an unsigned integral type (
uint,ulong, etc.) that provieds enough bits. - Assign each flag to a unique bit position, typically using powers of two (e.g., 1, 2, 4, 8...), and define them as enum members.
- Combine flags using the bitwise OR operator (
|). - Check for specific flags using either the bitwise AND operator (
&) or theHasFlag()method.
Each flag should correspnod to exactly one bit. Avoid assigning 0 to any meaningful flag since it represents "no flags set." Hexadecimal notation (e.g., 0x01) is often used because each hex digit maps cleanly to four bits. Starting with C# 7.0, binary literals (e.g., 0b0001) are also supported.
[Flags]
enum DisplayOptions : uint
{
BasicMode = 0x01, // bit 0
HighResolution= 0x02, // bit 1
AnimatedUI = 0x04, // bit 2
DarkTheme = 0x08 // bit 3
}
Combining and Checking Flags
To enable multiple options:
DisplayOptions config = DisplayOptions.BasicMode | DisplayOptions.AnimatedUI | DisplayOptions.DarkTheme;
To test for a single flag:
bool hasAnimation = config.HasFlag(DisplayOptions.AnimatedUI);
To test for multiple flags simultaneously:
DisplayOptions requiredFeatures = DisplayOptions.AnimatedUI | DisplayOptions.DarkTheme;
bool hasBoth = config.HasFlag(requiredFeatures);
Alternatively, use bitwise operations:
bool hasAnimationAndDark = (config & requiredFeatures) == requiredFeatures;
The Role of the [Flags] Attribute
The [Flags] attribute doesn't affect runtime behavior but improves tooling and string representation. Without it, calling ToString() on a combined value returns the numeric result (e.g., "12"). With [Flags], it returns a comma-separated list of active flags (e.g., "AnimatedUI, DarkTheme").
static void Main()
{
DisplayOptions opts = DisplayOptions.AnimatedUI | DisplayOptions.DarkTheme;
Console.WriteLine(opts.ToString()); // Output: "AnimatedUI, DarkTheme" (with [Flags])
}
Practical Usage Example
A class can interpret a flags-based configuration to set internal state:
class Renderer
{
public bool IsBasicMode { get; private set; }
public bool UsesHighRes { get; private set; }
public bool HasAnimations { get; private set; }
public bool UsesDarkTheme { get; private set; }
public void ApplySettings(DisplayOptions settings)
{
IsBasicMode = settings.HasFlag(DisplayOptions.BasicMode);
UsesHighRes = settings.HasFlag(DisplayOptions.HighResolution);
HasAnimations = settings.HasFlag(DisplayOptions.AnimatedUI);
UsesDarkTheme = settings.HasFlag(DisplayOptions.DarkTheme);
}
}