Understanding Enumerations (enum) in C#


An enumeration, often referred to as enums, are a great C# programming language feature that allows developers to define a set of named integral constants. Enums add a meaningful name to otherwise numeric values that makes the code more readable and easier to maintain. For example, particularly useful when you’re working with a variable that can only take one out of a small set of possible values.

In this article we will go through what exactly enumerations are and how they are used. First, we’ll look at basic usage; in the case of enum values in if statements, using foreach on enums, getting descriptions from enums, and giving numbers to enum members. These will break down each topic to explain it in great detail so you can fully understand enums in C#.

What Is an Enumeration?

A user defined value type that is theoretically an enumeration is simply a named collection of constants, all of which are values (technically, of the type int). Enums are value types and inherit from System.Enum. Each element within an enum defaults to the underlying type of int, but can be any integral numeric type (byte, sbyte, short, ushort, int, uint, long, or ulong).

An enum allows you to work with constants in a set, and your values are of the same ‘type’ which ensures they are syntactically correct. Enums allow you to say what you mean instead of senselessly filling your code with magic numbers or strings, thereby increasing code clarity and reducing errors. You could for example use DayOfWeek.Monday instead of 0 for Monday.

It also makes your code more maintainable. That way if you need to change the underlying values, you can do it on one place without having to rewrite the rest of your coding. Furthermore, enums also give support for IntelliSense in IDE like Visual Studio, giving list of possible values when developing.

Examples

Basic Usage

In order to declare an enum in C#, you use the enum keyword to define the enum and a list of enum members are placed in braces. Here’s a basic example:

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

For this example, DaysOfWeek is an enum with seven members standing for the days of the week. By default, the underlying values will begin at 0, and increment by 1 each for every subsequent value. Sunday is 0, Monday is 1 and so on.

You can use the enum in your code like this:

DaysOfWeek today = DaysOfWeek.Tuesday;
Console.WriteLine($"Today is {today}");

This will output:

Today is Tuesday

Enums can be converted to their underlying integer values and vice versa:

int dayValue = (int)DaysOfWeek.Friday;
Console.WriteLine($"Numeric value of Friday is {dayValue}"); // Outputs: 5

DaysOfWeek day = (DaysOfWeek)6;
Console.WriteLine($"Day with numeric value 6 is {day}"); // Outputs: Saturday

Enum Value in an if Statement

You can use enums in conditional statement to control the flow of your program depending on the enum value. Here’s an example:

enum TrafficLight
{
    Red,
    Yellow,
    Green
}

TrafficLight signal = TrafficLight.Yellow;

if (signal == TrafficLight.Red)
{
    Console.WriteLine("Stop!");
}
else if (signal == TrafficLight.Yellow)
{
    Console.WriteLine("Get Ready...");
}
else if (signal == TrafficLight.Green)
{
    Console.WriteLine("Go!");
}

Here in this code we compare the signal variable against the various values of the TrafficLight enum to decide what action to do. Using numeric or string literals is more error prone and much less readable than this approach.

That’s why we can use enums in if statements to make sure that only valid values are compared, avoiding runtime errors. The enum also ensures that the code is self documenting because, all the meaning from the enum names.

Enum in a foreach Loop

There is a foreach loop combined with Enum. GetValues method by which you can iterate over all the values of an enum. If you need to display all enum members, or do something on them, it is useful.

enum Planet
{
    Mercury,
    Venus,
    Earth,
    Mars,
    Jupiter,
    Saturn,
    Uranus,
    Neptune
}

foreach (Planet planet in Enum.GetValues(typeof(Planet)))
{
    Console.WriteLine(planet);
}

This will output:

Mercury
Venus
Earth
Mars
Jupiter
Saturn
Uranus
Neptune

With enums, we’re able to iterate over them, so that if our enum ever changes, our code is able to adapt automatically without having to manually manage hard coded lists. When populating dropdowns or menus in a user interface it is especially helpful.

Retrieve Enum Description

But there are times when you want to associate a description with each enum member so that they can be displayed. To be able to do this you could use the DescriptionAttribute from the System.ComponentModel namespace.

First, decorate your enum members with the DescriptionAttribute:

using System.ComponentModel;

enum OrderStatus
{
    [Description("Order is pending")]
    Pending,
    [Description("Order has been shipped")]
    Shipped,
    [Description("Order delivered to customer")]
    Delivered,
    [Description("Order was canceled")]
    Canceled
}

Next, create a method to retrieve the description:

using System;
using System.Reflection;

string GetEnumDescription(Enum value)
{
    FieldInfo fi = value.GetType().GetField(value.ToString());
    DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);

    if (attributes.Length > 0)
        return attributes[0].Description;
    else
        return value.ToString();
}

Now, you can use this method to get the descriptions:

OrderStatus status = OrderStatus.Delivered;
Console.WriteLine(GetEnumDescription(status)); // Outputs: Order delivered to customer

If you need to display user friendly text in the UI or in logs then storing the enum descriptions is useful.

Assign Enum Numbers

Enum members have their underlying values starting from 0 by default. Yet you can set enum members to specific value(s). When the enum values correspond to fixed values, error codes or flags for example, this is especially useful.

enum ErrorCode
{
    None = 0,
    NotFound = 404,
    ServerError = 500,
    Unauthorized = 401
}
ErrorCode code = ErrorCode.NotFound;
Console.WriteLine($"Error {(int)code}: {code}"); // Outputs: Error 404: NotFound

This is important when working with APIs, databases or hardware, as soon as you assign a specific numbers it guaranties that your enums is matching outwards definition or protocol.

You can also define enums with non-sequential values:

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

Using bitwise operations:

FileAccess permissions = FileAccess.Read | FileAccess.Write;
Console.WriteLine(permissions); // Outputs: Read, Write

This makes assigning numbers in a way that we can combine enum values with bitwise operators, which gives us something to use literally flags and permissions like this.

Conclusion

Enumerations in C# are a very useful part of our toolset which can make your code both read and maintainable. Enums provide a meaning to constant values by giving them more meaningful names which helps preventing errors at the same time.

In this post, we’ve covered what enums are, how to work with them in conditional statements, how to loop through enums, look at their descriptions and assigning some specific numeric values to them. That will help you making efficient use of enums in your C# applications.

Learn to use enums in your coding practices to write better, maintenance friendlier code. Also, they make your code easier to understand and they enforce valid values for your values while forcing fewer bugs overall.

,