NeuroAgent

Flags Enum Attribute in C#: Complete Guide

Learn what the [Flags] attribute means in C# and how to use it effectively. Complete guide with examples of bitwise operations, best practices, and when to use flags enums vs regular enums.

Question

What does the [Flags] enum attribute mean in C#?

From time to time I see enums like the following:

csharp
[Flags]
public enum Options 
{
    None    = 0,
    Option1 = 1,
    Option2 = 2,
    Option3 = 4,
    Option4 = 8
}

I don’t understand what exactly the [Flags] attribute does. Can someone provide a clear explanation with examples of how to use it effectively in C#?

NeuroAgent

The [Flags] attribute in C# indicates that an enumeration can be treated as a bit field, allowing it to represent multiple values simultaneously through bitwise operations. This attribute enables you to combine enum values using logical operators like OR (|), AND (&), and XOR (^), making it ideal for scenarios where you need to represent multiple options or settings in a single field. When properly implemented with powers of two values, the [Flags] attribute provides a memory-efficient and performant way to handle collections of related options.

Contents

What is the [Flags] Attribute?

The [Flags] attribute is a custom attribute that tells the .NET runtime that an enumeration should be treated as a collection of bit flags rather than as a set of mutually exclusive values. According to the official Microsoft documentation, use the FlagsAttribute custom attribute for an enumeration only if a bitwise operation (AND, OR, EXCLUSIVE OR) is to be performed on a numeric value.

The key difference between a regular enum and a flags enum is that:

  • Regular enum: Represents exactly one value from the set (like single-choice options)
  • Flags enum: Can represent any combination of values from the set (like multiple-choice options)

For example, if you have a file permissions enum, a regular enum might force you to choose only “Read” or “Write”, but a flags enum allows you to have both “Read” and “Write” permissions simultaneously.

Key Insight: The [Flags] attribute doesn’t change the underlying behavior of bitwise operations - it’s more about semantic clarity and enabling better debugging and string formatting capabilities.

How to Properly Define a Flags Enum

To create an effective flags enum, you must follow these critical rules:

1. Use Powers of Two Values

Each flag value must be a power of two (1, 2, 4, 8, 16, 32, etc.). This ensures that each flag occupies a unique bit position in the binary representation, preventing overlap.

csharp
[Flags]
public enum FilePermissions
{
    None    = 0,    // 0000
    Read    = 1,    // 0001
    Write   = 2,    // 0010
    Execute = 4     // 0100
}

2. Include a None Value

Always include a None = 0 value to represent the absence of any flags. This is particularly useful for initialization and comparison operations.

3. Consider Common Combinations

For frequently used flag combinations, create dedicated enum members. As Microsoft documentation suggests:

csharp
[Flags]
public enum FilePermissions
{
    None       = 0,
    Read       = 1,    // 0001
    Write      = 2,    // 0010
    Execute    = 4,    // 0100
    ReadWrite  = Read | Write,    // 0011
    All        = Read | Write | Execute  // 0111
}

4. Use Binary Notation for Clarity

For better readability, especially with larger numbers, you can use binary notation:

csharp
[Flags]
public enum AdvancedOptions
{
    None            = 0b0000_0000,
    FastProcessing  = 0b0000_0001,
    MemoryOptimized = 0b0000_0010,
    ThreadSafe      = 0b0000_0100,
    DebugMode       = 0b0000_1000
}

Common Bitwise Operations with Flags

Flags enums work with bitwise operations. Here are the most commonly used operations:

Setting Flags (OR Operation)

Use the bitwise OR operator (|) to combine multiple flags:

csharp
var permissions = FilePermissions.Read | FilePermissions.Write;
// Result: ReadWrite (3 in binary: 0011)

Checking Flags (AND Operation)

Use the bitwise AND operator (&) to check if specific flags are set:

csharp
if ((permissions & FilePermissions.Read) == FilePermissions.Read)
{
    Console.WriteLine("Read permission is set");
}

// More concise way:
if (permissions.HasFlag(FilePermissions.Read))
{
    Console.WriteLine("Read permission is set");
}

Removing Flags

Use the bitwise AND with the complement to remove flags:

csharp
// Remove Write permission
permissions = permissions & ~FilePermissions.Write;

Toggling Flags

Use the XOR operator (^) to toggle flags (add if not present, remove if present):

csharp
permissions = permissions ^ FilePermissions.Execute;

Checking Multiple Flags

To check if multiple flags are set:

csharp
if ((permissions & (FilePermissions.Read | FilePermissions.Write)) != 0)
{
    Console.WriteLine("Either Read or Write permission is set");
}

Best Practices and Examples

Example 1: File Permissions

csharp
[Flags]
public enum FilePermissions
{
    None    = 0,
    Read    = 1,
    Write   = 2,
    Execute = 4,
    Delete  = 8,
    Full    = Read | Write | Execute | Delete
}

// Usage
var userPermissions = FilePermissions.Read | FilePermissions.Write;

// Check permissions
if (userPermissions.HasFlag(FilePermissions.Read))
{
    Console.WriteLine("User can read files");
}

// Add permission
userPermissions |= FilePermissions.Execute;

// Remove permission
userPermissions &= ~FilePermissions.Write;

Example 2: Days of the Week

csharp
[Flags]
public enum DaysOfWeek
{
    None = 0,
    Monday = 1,
    Tuesday = 2,
    Wednesday = 4,
    Thursday = 8,
    Friday = 16,
    Saturday = 32,
    Sunday = 64,
    Weekdays = Monday | Tuesday | Wednesday | Thursday | Friday,
    Weekend = Saturday | Sunday
}

// Usage
var workSchedule = DaysOfWeek.Monday | DaysOfWeek.Wednesday | DaysOfWeek.Friday;

// Check if working on weekend
if ((workSchedule & DaysOfWeek.Weekend) != 0)
{
    Console.WriteLine("Working on weekend");
}

Example 3: User Preferences

csharp
[Flags]
public enum UserPreferences
{
    None = 0,
    DarkMode = 1,
    AutoSave = 2,
    Notifications = 4,
    Analytics = 8,
    HighContrast = 16
}

// Combining preferences
var preferences = UserPreferences.DarkMode | UserPreferences.AutoSave | UserPreferences.Notifications;

// Checking bit by bit
foreach (UserPreference preference in Enum.GetValues(typeof(UserPreference)))
{
    if (preferences.HasFlag(preference))
    {
        Console.WriteLine($"Preference enabled: {preference}");
    }
}

Performance Considerations

According to Dot Net Perls, when using enum flags, you should be concerned about performance. Bitwise operations are extremely fast, but be mindful of:

  • Memory usage: Flags enums use the same memory as integer types
  • Validation overhead: Always validate user input for flags enums
  • String formatting: Flags enums have special string formatting behavior

Parsing and Formatting Flags

String Parsing

You can parse comma-separated strings into flags:

csharp
string permissionsString = "Read,Write";
FilePermissions permissions = (FilePermissions)Enum.Parse(typeof(FilePermissions), permissionsString);

String Formatting

Flags enums have special behavior when converted to strings:

csharp
FilePermissions permissions = FilePermissions.Read | FilePermissions.Write;
Console.WriteLine(permissions.ToString()); 
// Output: "Read, Write"

Custom Formatting

For better control over the string representation:

csharp
[Flags]
public enum FilePermissions
{
    None = 0,
    Read = 1,
    Write = 2,
    // ...
    
    public override string ToString()
    {
        return this switch
        {
            Read => "Read-only",
            Write => "Write-only", 
            Read | Write => "Read/Write",
            Full => "Full access",
            _ => base.ToString()
        };
    }
}

When to Use [Flags] vs Regular Enums

Use Regular Enums When:

  • Only one value from the enum should be selected at a time
  • The values represent mutually exclusive states or options
  • You need string-to-enum conversion without bitwise operations
  • The enum values don’t need to be combined

Use Flags Enums When:

  • Multiple values can be selected simultaneously
  • You need to represent combinations of options
  • Memory efficiency is important (storing multiple booleans in one field)
  • You’re working with system-level flags, permissions, or settings

Decision Flow

Do you need to represent multiple values at once?
├── Yes → Use [Flags] enum
│   └── Are values mutually exclusive?
│       └── Yes → Consider if flags are really needed
└── No → Use regular enum

Common Use Cases for Flags Enums:

  1. Permissions and Access Control: Read, Write, Execute permissions
  2. Configuration Settings: Various application options and preferences
  3. Error Codes: Multiple error conditions that can occur simultaneously
  4. Feature Flags: Enable/disable multiple features
  5. Days/Times: Days of the week, time periods
  6. File Attributes: Hidden, System, Archive, Read-only

Conclusion

The [Flags] attribute in C# is a powerful tool for representing multiple values in a single enumeration. When used correctly with powers of two values, it provides an efficient and clean way to handle collections of related options. Key takeaways include:

  1. Always use powers of two (1, 2, 4, 8, etc.) for flag values to ensure no overlap
  2. Include a None value (0) for clear initialization and comparison
  3. Use bitwise operators (|, &, ~, ^) to manipulate flags
  4. Consider common combinations as dedicated enum members for better readability
  5. Validate user input when working with flags to prevent invalid combinations

Flags enums are particularly useful for permissions, settings, and any scenario where you need to represent multiple boolean options efficiently. By following these best practices, you can create clean, maintainable code that takes full advantage of the power of bitwise operations.

Sources

  1. What does the [Flags] Enum Attribute mean in C#? - Stack Overflow
  2. System.FlagsAttribute class - .NET | Microsoft Learn
  3. FlagsAttribute Class (System) | Microsoft Learn
  4. C# - enum Flags Attribute Examples - Dot Net Perls
  5. Flags Attribute For Enum in C# - Code Maze
  6. Defining and Using Enums as Bit Flags in C# - Aaron Bos
  7. Enum Flags in C# - DEV Community
  8. C# Enum Flags Attribute - TheDeveloperBlog