C# enum

In C#, an enum, or enumeration, is a value type that represents a fixed set of named constants. Enums make code easier to read by replacing unexplained numeric values with meaningful names.

For example, a program can use values such as OrderStatus.Pending and OrderStatus.Shipped instead of using numbers such as 0 and 1.

Each enum member has an underlying integral value. By default, the first member has the value 0, and each subsequent member is assigned the next integer.

C# enum declaration syntax

The syntax to declare an enum is shown below:

</>
Copy
 enum EnumName{
     CONSTANT_NAME_1,
     CONSTANT_NAME_2,
     CONSTANT_NAME_N
 }

EnumName is the name of the enum type. The identifiers inside the braces are its named members.

Enum names and members are commonly written using Pascal case in modern C# code.

</>
Copy
enum OrderStatus
{
    Pending,
    Processing,
    Shipped,
    Delivered
}

Declaring and using a C# enum value

In the following example, we use enum named Operation to store constants that represent mathematical operations.

This example demonstrates the declaration of Enum, initializing a variable with value of this Enum type, and then accessing the elements of this Enum.

Program.cs

</>
Copy
using System;

namespace CSharpExamples {
    enum Operation{
        ADDITION,
        SUBTRACTION,
        MULTIPLICATION
    }
    class Program {
        static void Main(string[] args) {
            int a = 10;
            int b = 4;
            int result=0;

            Operation op = Operation.ADDITION;

            if(op==Operation.ADDITION){
                result = a+b;
            } else if(op==Operation.SUBTRACTION){
                result = a-b;
            } else if(op==Operation.MULTIPLICATION){
                result = a*b;
            }
            Console.WriteLine("Result is : "+result);
        }
    }
}

Output

Result is : 14

Let us analyse this example.

To define an enum named Operations, we used the following code snippet.

</>
Copy
 enum Operation{
     ADDITION,
     SUBTRACTION,
     MULTIPLICATION
 }

If we do not specify any value to the named constant, the first constant will take value of 0, and the rest would be incremented one by one.

So, here ADDITION = 0, SUBTRACTION = 1 and MULTIPLICATION = 2.

Inside the program, we defined a variable of type Operation and assigned a value to it.

</>
Copy
 Operation op = Operation.ADDITION;

An enum variable can normally store only values belonging to that enum type. A member is referenced by writing the enum type name, a period, and the member name.

Printing C# enum names and integer values

Enum members have both a name and an underlying numeric value. Printing the enum member directly displays its name. Casting it to an integer displays its underlying number.

Program.cs

</>
Copy
using System;

namespace CSharpExamples {
    enum Operation{
        ADDITION,
        SUBTRACTION,
        MULTIPLICATION
    }
    class Program {
        static void Main(string[] args) {
            Console.WriteLine("Operation.ADDITION (without parsing to int) : "+Operation.ADDITION);
            Console.WriteLine("Operation.ADDITION : "+(int)Operation.ADDITION);
            Console.WriteLine("Operation.SUBTRACTION : "+(int)Operation.SUBTRACTION);
            Console.WriteLine("Operation.MULTIPLICATION : "+(int)Operation.MULTIPLICATION);
        }
    }
}

Output

Operation.ADDITION (without parsing to int) : ADDITION
Operation.ADDITION : 0
Operation.SUBTRACTION : 1
Operation.MULTIPLICATION : 2

The value without parsing prints the named constant as is. If we type cast the enum constant to integer, we get their respective integer values.

Assigning explicit values to C# enum members

You can provide your own integer values to the named constants in the enum. Explicit values are useful when an enum must match values stored in a database, exchanged through an API, or defined by an external protocol.

Program.cs

</>
Copy
using System;

namespace CSharpExamples {
    enum Operation{
        ADDITION = 14,
        SUBTRACTION = 17,
        MULTIPLICATION = 27
    }
    class Program {
        static void Main(string[] args) {
            Console.WriteLine("Operation.ADDITION (without parsing to int) : "+Operation.ADDITION);
            Console.WriteLine("Operation.ADDITION : "+(int)Operation.ADDITION);
            Console.WriteLine("Operation.SUBTRACTION : "+(int)Operation.SUBTRACTION);
            Console.WriteLine("Operation.MULTIPLICATION : "+(int)Operation.MULTIPLICATION);
        }
    }
}

Output

Operation.ADDITION (without parsing to int) : ADDITION
Operation.ADDITION : 14
Operation.SUBTRACTION : 17
Operation.MULTIPLICATION : 27

Explicit enum values do not need to be consecutive. However, every assigned value must be a constant that can be represented by the enum’s underlying type.

Automatic numbering after an assigned C# enum value

If you assign a value only to the first constant, the rest of the constants will take a value incremented of its previous constant’s value.

Program.cs

</>
Copy
using System;

namespace CSharpExamples {
    enum Operation{
        ADDITION = 34,
        SUBTRACTION,
        MULTIPLICATION
    }
    class Program {
        static void Main(string[] args) {
            Console.WriteLine("Operation.ADDITION : "+(int)Operation.ADDITION);
            Console.WriteLine("Operation.SUBTRACTION : "+(int)Operation.SUBTRACTION);
            Console.WriteLine("Operation.MULTIPLICATION : "+(int)Operation.MULTIPLICATION);
        }
    }
}

Output

Operation.ADDITION : 34
Operation.SUBTRACTION : 35
Operation.MULTIPLICATION : 36

The automatic increment also applies after any explicitly assigned member, not only the first member.

</>
Copy
enum StatusCode
{
    Success = 200,
    Created,
    Accepted,
    BadRequest = 400,
    Unauthorized
}

In this declaration, Created is 201, Accepted is 202, and Unauthorized is 401.

Using a C# enum with a switch statement

Enums work well with switch statements because each case can use a clearly named enum member.

</>
Copy
using System;

class Program
{
    enum TrafficLight
    {
        Red,
        Yellow,
        Green
    }

    static void Main()
    {
        TrafficLight light = TrafficLight.Green;

        switch (light)
        {
            case TrafficLight.Red:
                Console.WriteLine("Stop");
                break;

            case TrafficLight.Yellow:
                Console.WriteLine("Wait");
                break;

            case TrafficLight.Green:
                Console.WriteLine("Go");
                break;
        }
    }
}
Go

Using enum members in the cases makes the intent clearer than comparing numeric values such as 0, 1, and 2.

Converting a C# enum to a string or integer

An enum value can be converted to its member name with ToString(). It can be converted to its underlying numeric value with an explicit cast.

</>
Copy
using System;

class Program
{
    enum Priority
    {
        Low = 1,
        Medium = 2,
        High = 3
    }

    static void Main()
    {
        Priority priority = Priority.High;

        string name = priority.ToString();
        int number = (int)priority;

        Console.WriteLine(name);
        Console.WriteLine(number);
    }
}
High
3

Parsing a string into a C# enum safely

Enum.TryParse can convert text into an enum value without throwing an exception when the input is invalid. The optional third argument can make the comparison case-insensitive.

</>
Copy
using System;

class Program
{
    enum AccessLevel
    {
        Guest,
        User,
        Administrator
    }

    static void Main()
    {
        string input = "administrator";

        if (Enum.TryParse(input, true, out AccessLevel level))
        {
            Console.WriteLine(level);
        }
        else
        {
            Console.WriteLine("Invalid access level");
        }
    }
}
Administrator

When numeric text is accepted as input, TryParse may produce a numeric enum value even when no named member has that value. Use Enum.IsDefined when the program must accept only declared members.

Checking whether a C# enum value is defined

An explicit cast can create an enum value that has no corresponding named member. Enum.IsDefined checks whether a value is declared in the enum.

</>
Copy
using System;

class Program
{
    enum Membership
    {
        Basic = 1,
        Standard = 2,
        Premium = 3
    }

    static void Main()
    {
        Membership membership = (Membership)5;

        bool isDefined = Enum.IsDefined(typeof(Membership), membership);
        Console.WriteLine(isDefined);
    }
}
False

Changing the underlying type of a C# enum

The default underlying type of an enum is int. You can explicitly use another integral type: byte, sbyte, short, ushort, int, uint, long, or ulong.

</>
Copy
enum FilePermission : byte
{
    None = 0,
    Read = 1,
    Write = 2
}

Choose a different underlying type only when storage size, interoperability, or a required numeric range makes it necessary.

Combining C# enum values with the Flags attribute

Use the [Flags] attribute when one variable must represent a combination of enum options. Flag values are usually assigned powers of two so that each option occupies a separate bit.

</>
Copy
using System;

[Flags]
enum Permission
{
    None = 0,
    Read = 1,
    Write = 2,
    Execute = 4
}

class Program
{
    static void Main()
    {
        Permission permissions = Permission.Read | Permission.Write;

        Console.WriteLine(permissions);
        Console.WriteLine(permissions.HasFlag(Permission.Write));
    }
}
Read, Write
True

The bitwise OR operator, |, combines flags. The HasFlag method checks whether a particular option is present.

Important C# enum rules and limitations

  • An enum is a value type and ultimately derives from System.Enum.
  • The default underlying type is int.
  • Enum members must use constant integral values.
  • Different enum members may share the same numeric value, although this can make conversions and output less clear.
  • An enum cannot inherit from another enum or class.
  • Enum member names are preferable to raw numbers because they communicate the purpose of each value.
  • A cast from an integer does not guarantee that the result corresponds to a declared enum member.

C# enum and const integer comparison

FeatureC# enumInteger constants
Type safetyValues belong to a distinct enum type.Values are ordinary integers.
ReadabilityMembers have descriptive names grouped under one type.Related constants may be scattered across a class.
Switch statementsCases clearly identify valid named states.Cases use numeric values or separate constants.
String conversionMember names are available through ToString().Numbers do not automatically provide descriptive names.

Common mistakes when using C# enums

  • Assuming every numeric value is declared: Validate external numeric input with Enum.IsDefined when unnamed values are not allowed.
  • Using sequential values as permanent external identifiers: Adding or reordering members can change implicit values. Assign explicit values when compatibility matters.
  • Using Flags without powers of two: Combined values may overlap and become difficult to interpret.
  • Comparing enum values to raw integers: Prefer named members such as Status.Active to preserve type clarity.
  • Using enums for frequently changing data: Values managed by users or stored as records usually belong in a database or configuration rather than a compiled enum.

C# enum frequently asked questions

What is the default value of a C# enum variable?

The default numeric value is 0. If the enum does not declare a member with the value 0, the variable can still contain that unnamed value. Defining a member such as None = 0 is often useful when zero represents a valid default state.

Can a C# enum contain string values?

No. Enum members use integral values. To associate display text with an enum member, use a method, a lookup, an attribute, or another mapping mechanism.

Can two C# enum members have the same value?

Yes. C# allows multiple enum members to share one underlying value. However, converting that value to text may return only one of the matching names, so duplicate values should be used deliberately.

How do you loop through all C# enum values?

Use Enum.GetValues<TEnum>() in current C# versions and iterate through the returned values with foreach.

</>
Copy
foreach (Priority value in Enum.GetValues<Priority>())
{
    Console.WriteLine(value);
}

When should the Flags attribute be used with a C# enum?

Use [Flags] when multiple options can be active at the same time, such as file permissions or feature settings. Do not use it when the values are mutually exclusive states such as pending, approved, and rejected.

C# enum tutorial summary

In this C# Tutorial, we learned how to declare and use a C# enum, access member names and numeric values, assign explicit values, parse strings, validate enum values, select an underlying type, and combine options with the [Flags] attribute.