ZetCode

C# enum

last modified October 15, 2026

In this article we show how to work with the enum type in C#.

Enumerated type (also called enumeration or enum) is a data type consisting of a set of named values. A variable that has been declared as having an enumerated type can be assigned any of the enumerators as a value. Enumerations make the code more readable.

We define an enumeration type with the enum keyword.

enum Difficulty
{
    Easy,
    Normal,
    Hard,
    VeryHard
}

By default, the associated constant values of enum members are of type int. They start with zero and increase by one following the definition text order. It is possible to define other types including byte, sbyte, short, ushort, uint, long, and ulong.

Enumerations are value types. An enum variable can hold any value of the underlying type, not only the values of the named members.

C# enum simple example

The following is a simple example with the enum type.

Program.cs
Day day = Day.Monday;

if (day == Day.Monday)
{
    Console.WriteLine("It is Monday");
}

Console.WriteLine(day);

foreach (var d in Enum.GetValues<Day>())
{
    Console.WriteLine((int) d);
}

Console.WriteLine(string.Join(", ", Enum.GetNames<Day>()));

enum Day
{
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
}

We create an enumeration for week days.

enum Day
{
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
}

The enumeration is created with the enum keyword. The Monday, Tuesday, ... members store in fact numbers 0..6.

Day day = Day.Monday;

We have a variable called day which is of the enumerated type Day. It is initialized to Monday.

if (day == Day.Monday)
{
    Console.WriteLine("It is Monday");
}

This code is more readable than comparing a day variable to some number.

Console.WriteLine(day);

This line prints Monday to the console.

foreach (var d in Enum.GetValues<Day>())
{
    Console.WriteLine((int) d);
}

This loop prints 0..6 to the console. The generic GetValues method returns an array of the values of the specified enumeration. We cast each value to its underlying integral value. For a computer, an enum is just a number.

Console.WriteLine(string.Join(", ", Enum.GetNames<Day>()));

The GetNames method returns an array of the names of the members.

$ dotnet run
It is Monday
Monday
0
1
2
3
4
5
6
Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday

We can provide our own values for the enum members.

Program.cs
foreach (var day in Enum.GetValues<Day>())
{
    Console.WriteLine((int) day);
}

enum Day
{
    Monday = 10,
    Tuesday = 11,
    Wednesday = 12,
    Thursday = 13,
    Friday = 14,
    Saturday = 15,
    Sunday = 16
}

In the example, we provide values 10 through 16 to the members of the Day enumeration.

$ dotnet run
10
11
12
13
14
15
16

The following example should not be used; it only clarifies how enum type works.

Program.cs
foreach (var day in Enum.GetValues<Days>())
{
    Console.WriteLine((int) day);
}

enum Days
{
    Monday,
    Tuesday,
    Wednesday = 8,
    Thursday,
    Friday,
    Saturday,
    Sunday
}

We start with default values for enum members, then we set the Wednesday member to eight. The next member Thursday is set to nine etc.

$ dotnet run
0
1
8
9
10
11
12

C# enum different type for members

In the next example, we change the data type for the enumeration members.

Program.cs
Season s1 = Season.Spring;
Season s2 = Season.Autumn;

Console.WriteLine(s1);
Console.WriteLine(s2);

Console.WriteLine("----------------------");

Console.WriteLine(s1.GetType());
Console.WriteLine(Enum.GetUnderlyingType(s1.GetType()));

enum Season : byte
{
    Spring = 1,
    Summer = 2,
    Autumn = 3,
    Winter = 4
}

We have the Season enumeration. The underlying type of its members is set to byte. The Enum.GetUnderlyingType method returns the underlying type of the enumeration.

$ dotnet run
Spring
Autumn
----------------------
Season
System.Byte

C# enum conversions

It is possible to do explicit conversions between the enumeration type and its underlying integral type.

Program.cs
var p1 = Priority.Minor;

Console.WriteLine($"Integral value of {p1} is {(int) p1}");

var p2 = (Priority) 1;
Console.WriteLine(p2);

var p3 = (Priority) 2;
Console.WriteLine(p3);

enum Priority
{
    Minor,
    Major,
    Critical
}

There are three explicit conversions in the example.

Console.WriteLine($"Integral value of {p1} is {(int) p1}");

In this code line we convert the p1 value to its underlying integral value using the (int) cast.

var p2 = (Priority) 1;
Console.WriteLine(p2);

Here we convert the integer value to the enumeration type.

$ dotnet run
Integral value of Minor is 0
Major
Critical

C# enum Flags

With the Flags attribute, we can turn an enumeration into a bit field. It can be then used as a set of flags. (The associated values of those enum members should be the powers of two.)

This way the enumeration can represent a combination of choices. We can use the bitwise logical operators | or & to combine choices or intersect combinations of choices.

Program.cs
var readWrite = Permissions.Read | Permissions.Write;
Console.WriteLine(readWrite);

[Flags]
enum Permissions
{
    Execute = 0b_0000_0001,
    Write = 0b_0000_0010,
    Read = 0b_0000_0100
}

In the example, we define read & write permission with the | operator.

$ dotnet run
Write, Read

In the next example, we check, add, and remove flags.

Program.cs
var perms = Permissions.Read | Permissions.Write;
Console.WriteLine(perms);

Console.WriteLine(perms.HasFlag(Permissions.Read));
Console.WriteLine(perms.HasFlag(Permissions.Execute));

perms |= Permissions.Execute;
Console.WriteLine(perms);

perms &= ~Permissions.Write;
Console.WriteLine(perms);

Console.WriteLine((int) perms);

[Flags]
enum Permissions
{
    None = 0,
    Execute = 0b_0000_0001,
    Write = 0b_0000_0010,
    Read = 0b_0000_0100
}

It is a good practice to define a None member with the value 0 in a flags enumeration.

Console.WriteLine(perms.HasFlag(Permissions.Read));

The HasFlag method determines whether the given flag is set.

perms |= Permissions.Execute;

We add a flag with the |= operator.

perms &= ~Permissions.Write;

We remove a flag with the &= and ~ operators.

$ dotnet run
Write, Read
True
False
Execute, Write, Read
Execute, Read
5

C# Enum.IsDefined

The Enum.IsDefined method checks if a given integral value, or its name as a string, exists in the specified enumeration.

Program.cs
Console.WriteLine(Enum.IsDefined(typeof(Priority), 0));
Console.WriteLine(Enum.IsDefined(typeof(Priority), 4));

Console.WriteLine("-------------");

Console.WriteLine(Enum.IsDefined(typeof(Priority), "Critical"));
Console.WriteLine(Enum.IsDefined(typeof(Priority), "Medium"));

Console.WriteLine("-------------");

Console.WriteLine(Enum.IsDefined(typeof(Priority), Priority.Major));
Console.WriteLine(Enum.IsDefined(typeof(Priority), Priority.Minor | Priority.Critical));

[Flags]
enum Priority
{
    Minor = 1,
    Major = 2,
    Critical = 4
}

In the example, we use the Enum.IsDefined method to check if certain values exist in the Priority enumeration.

Console.WriteLine(Enum.IsDefined(typeof(Priority), Priority.Minor | Priority.Critical));

A combination of flags is not a defined member; therefore, the method returns false.

$ dotnet run
False
True
-------------
True
False
-------------
True
False

C# Enum.Parse and Enum.TryParse

The Enum.Parse and Enum.TryParse methods convert the string representation of a member name or a numeric value to an enumeration value.

Program.cs
string[] vals = ["Major", "critical", "Medium", "1"];

foreach (var val in vals)
{
    if (Enum.TryParse(val, true, out Priority p))
    {
        Console.WriteLine($"{val} -> {p}");
    }
    else
    {
        Console.WriteLine($"{val} -> not a valid priority");
    }
}

var p2 = Enum.Parse<Priority>("Minor");
Console.WriteLine(p2);

enum Priority
{
    Minor,
    Major,
    Critical
}

We parse four strings with TryParse. The second parameter makes the parsing case-insensitive. The method returns false if the conversion fails. The Parse method throws an ArgumentException instead.

$ dotnet run
Major -> Major
critical -> Critical
Medium -> not a valid priority
1 -> Major
Minor

Note that numeric strings are accepted even if the number is not a defined member. For instance, "7" would be parsed successfully. To validate the result, we can use the Enum.IsDefined method.

C# enum switch expression

Enumerations are often used with the switch expression.

Program.cs
foreach (var day in Enum.GetValues<Day>())
{
    var msg = day switch
    {
        Day.Saturday or Day.Sunday => "weekend",
        _ => "weekday"
    };

    Console.WriteLine($"{day} is a {msg}");
}

enum Day
{
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
}

We go over the days and determine whether each of them is a weekday or a weekend day. The or pattern combines two members in one arm.

$ dotnet run
Monday is a weekday
Tuesday is a weekday
Wednesday is a weekday
Thursday is a weekday
Friday is a weekday
Saturday is a weekend
Sunday is a weekend

Source

Enumeration types - language reference

In this article we have worked with enumerations in C#.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all C# tutorials.