C#
Programming
Flags
Enum
Bitwise Operations

How to Compare Flags in C?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Despite the short title, this topic is really about flag-style enums in C#. Comparing flags is different from comparing ordinary enum values because one variable can contain several options at the same time.

Define Flags With Powers of Two

A flags enum should assign each option its own bit. That means powers of two rather than consecutive integers.

csharp
1using System;
2
3[Flags]
4public enum Permission
5{
6    None = 0,
7    Read = 1,
8    Write = 2,
9    Delete = 4,
10    Admin = 8
11}

None = 0 is important because it gives the enum an unambiguous empty state.

To combine flags, use the bitwise OR operator.

csharp
Permission current = Permission.Read | Permission.Write;
Console.WriteLine(current);

That value now contains two independent bits.

Check Whether a Flag Is Present

The standard comparison pattern is bitwise AND followed by equality with the flag you are testing.

csharp
1bool hasWrite = (current & Permission.Write) == Permission.Write;
2bool hasDelete = (current & Permission.Delete) == Permission.Delete;
3
4Console.WriteLine(hasWrite);
5Console.WriteLine(hasDelete);

This works because AND keeps only the overlapping bits. If the requested flag is present, the result matches that flag exactly.

Exact Equality Is a Different Question

A common bug is confusing "contains this flag" with "is exactly this one flag." Those are not the same comparison.

csharp
1Permission value = Permission.Read | Permission.Write;
2
3bool containsRead = (value & Permission.Read) == Permission.Read;
4bool exactlyRead = value == Permission.Read;
5
6Console.WriteLine(containsRead);
7Console.WriteLine(exactlyRead);

The first result is true because the Read bit exists. The second result is false because the value contains more than just Read.

Use HasFlag When Readability Matters

C# also provides HasFlag, which can make code easier to read.

csharp
bool canRead = current.HasFlag(Permission.Read);
Console.WriteLine(canRead);

For most application code this is perfectly fine. In performance-sensitive loops, some developers prefer the explicit bitwise expression because it makes the rule visible and avoids extra overhead.

Add and Remove Flags Safely

Flag comparisons are only part of the story. You also need to add and remove bits correctly.

csharp
1Permission value = Permission.None;
2value |= Permission.Read;
3value |= Permission.Write;
4value &= ~Permission.Read;
5
6Console.WriteLine(value);

The key operations are:

  • '| to add a flag'
  • '& plus comparison to test a flag'
  • '& ~flag to remove a flag'

You can wrap these rules in helpers if the enum is used heavily.

csharp
1public static class PermissionExtensions
2{
3    public static bool Contains(this Permission value, Permission flag)
4        => (value & flag) == flag;
5
6    public static Permission Add(this Permission value, Permission flag)
7        => value | flag;
8
9    public static Permission Remove(this Permission value, Permission flag)
10        => value & ~flag;
11}

That keeps calling code clean and reduces copy-paste mistakes.

Composite Flags Are Still Flags

Some applications define reusable combinations such as editor or owner roles.

csharp
1public static class PermissionGroups
2{
3    public const Permission Editor = Permission.Read | Permission.Write;
4    public const Permission Owner = Permission.Read | Permission.Write | Permission.Delete;
5}
6
7Permission role = PermissionGroups.Editor;
8Console.WriteLine(role.HasFlag(Permission.Delete));

These are still just bit combinations, so the same comparison rules apply.

Common Pitfalls

The biggest mistake is defining enum values as 1, 2, 3, 4 instead of powers of two. Once the binary representation overlaps, flag checks become unreliable.

Another common issue is using == to test presence when you really need a contains check. Developers also sometimes forget to define None = 0, which makes default values much harder to reason about.

Summary

  • Use [Flags] and powers-of-two values for flag enums in C#.
  • Combine flags with | and test presence with & or HasFlag.
  • Equality and containment are different comparisons.
  • Remove flags with value & ~flag.
  • Keep None = 0 so the empty state is explicit and predictable.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.