Enums in CSharp – A Simple Guide To Expressive Code

If you’re a software engineer or aspiring to be one, you’ll certainly have heard of Enums — Likely had to use them already, too! Enums in CSharp can be super helpful in allowing us to write more expressive code. But there are important things to understand about how they work as well!

Enums in CSharp help define a specific set of named integral constants, which provide a more meaningful representation of values in a program. This article provides guidance covering the benefits of enums, how to declare them, why we use them, and the limitations and alternatives of enums.

Let’s check out enums in CSharp!


What Are Enums?

Enums, or enumerations, are a fundamental data type in C#. They are an ordered set of named values, allowing developers to define a set of named, integral constants. Not only do enums provide a way to organize code and make it more readable, but they can also make it easier to write maintainable code — If you don’t misuse them!

There are many benefits to using enums in CSharp. Enums can eliminate the use of magic numbers (hard-coded values in the code), which are generally hard to read and understand. Once an enum is defined, developers can use it throughout the software, ensuring consistency and readability. Enums help reduce the possibility of errors or discrepancies occurring in code because the enum values do not change throughout the code. Plus, enums allow for readability and therefore easier testing and maintenance of code.

While enums present these benefits, it is important to always consider the scenario and determine if the use of an enum is appropriate. Enums should mainly be used when working with a finite set of values or when the variable will only be used for certain values. It is also important to note that it’s best to avoid a cumbersome enum that is used for a wide range of values.


How to Declare Enums in CSharp

To declare an enum in C#, you must follow several steps. In this section, we’ll go over the process of declaring enums in CSharp step by step, along with example code snippets for each step.

Step 1: Define the Enum

The first step in declaring an enum is to define it using the enum keyword, followed by the enum name. Generally, this is done in PascalCase and singular form. For example:

enum MonthOfYear
{ 
}

Step 2: Define the Enum Values

Next, you need to define the values for the enum. To do this, place each value on a new line, separated by a comma. Each value must be a valid identifier in C# and should be in PascalCase. For example:

enum MonthOfYear
{ 
    January,
    February,
    March,
    April,
    May,
    June,
    July,
    August,
    September,
    October,
    November,
    December
}

(Optional) Step 3: Assign Values to the Enum

If you want to assign specific values to the enum, you can use the = operator. By default, the first value in the enum will be assigned a value of 0, and each subsequent value will be incremented by 1. For example:

enum MonthOfYear
{ 
    January = 1,
    February,
    March,
    April,
    May,
    June,
    July,
    August,
    September,
    October,
    November,
    December
}

Best Practices for Declaring Enums

When declaring enums, you should follow these best practices:

  • Choose meaningful names for your enums that describe the values they represent.
  • Use PascalCase to name your enums and enum values.
  • When assigning values to your enums, avoid using values that may conflict with other values in your code.
  • Group related enums together in the same file.

Declaring enums is a straightforward process in C#, and following these best practices can help ensure that your code is organized, easy to read, and maintainable. Follow along with this video tutorial for more help:

YouTube player

Types of Enums in CSharp

An important aspect of working with enums in CSharp is understanding the different types available and their specific use cases. There are two primary types of enums in CSharp: the simple enum and the flags enum.

The simple enum is the default and most common type. It assigns each enum value a unique, sequential integer value. This allows enums to be used in a switch statement or other scenarios where a numeric value is required.

enum MonthOfYear
{ 
    January,
    February,
    March,
    April,
    May,
    June,
    July,
    August,
    September,
    October,
    November,
    December
}

The flags enum, on the other hand, is used to represent sets of flags or options. Each flag value corresponds to a single bit in a larger value, allowing multiple flags to be combined into a single value. This is commonly used when working with permissions or options.

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

When deciding which type of enum to use, consider the data being represented. If the enum values are mutually exclusive and there are no scenarios where multiple values need to be combined, a simple enum is likely appropriate. If the values represent combinations of flags or options, a flags enum may be more appropriate. You can check out this video for more information on flags enums:

YouTube player

Enumerations and Switch Statements

Enums are often used in conjunction with switch statements in C# to create simple code structures that organize and handle multiple paths of execution. A switch statement in C# works by evaluating a given expression and matching it to a list of potential cases. The cases contain a block of code that is executed when the expression matches.

Enumerations fit perfectly into the functionality of switch statements because each enumeration is essentially a predefined set of cases that can be handled by a switch statement. Instead of having to create individual if statements to handle each enumeration, a switch statement can handle all of these cases in a more organized and readable manner.

Here is an example code snippet for using enums with switch statements:

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

static void PrintDayOfWeek(DaysOfWeek day)
{
    switch (day)
    {
        case DaysOfWeek.Monday:
            Console.WriteLine("Monday");
            break;
        case DaysOfWeek.Tuesday:
            Console.WriteLine("Tuesday");
            break;
        case DaysOfWeek.Wednesday:
            Console.WriteLine("Wednesday");
            break;
        case DaysOfWeek.Thursday:
            Console.WriteLine("Thursday");
            break;
        case DaysOfWeek.Friday:
            Console.WriteLine("Friday");
            break;
        case DaysOfWeek.Saturday:
            Console.WriteLine("Saturday");
            break;
        case DaysOfWeek.Sunday:
            Console.WriteLine("Sunday");
            break;
        default:
            Console.WriteLine("Invalid day of week.");
            break;
    }
}

Notice how the enumerated values are used in a switch statement to output the corresponding day of the week. Without the use of enums, this code would contain numerous if statements or would be disorganized and difficult to follow. With enums, code is streamlined and easier to understand.


Enums and Object-Oriented Programming

Enums are a powerful tool in C# that can help improve code readability and organization, especially in object-oriented programming (OOP) paradigms. You can use enums with classes and interfaces to define a set of named constants that represent the possible states or values of an object or a property.

When using enums in OOP, it is important to first declare the enum using the appropriate syntax and naming convention. This allows for the creation of a strongly typed value that is easy to understand and use throughout the codebase. Enums can then be used in various ways, such as defining properties or method parameters.

Here is an example of how enums can be used with classes and interfaces in OOP:

public enum AccountType {
  Checking,
  Savings,
  Credit
}

public class BankAccount {
  public AccountType AccountType { get; set; }
  public float Balance { get; set; }
}

public interface IBankService {
  void Deposit(float amount, AccountType accountType);
  void Withdraw(float amount, AccountType accountType);
}

In this example, an enum is declared to represent different types of bank accounts. This enum is then used as a property type in the BankAccount class, allowing for easy classification of account types. The IBankService interface also utilizes the enum as a method parameter, allowing for easy and clear communication between the service and client code.

Overall, enums serve as a useful tool in object-oriented programming by improving code readability, organization, and communication between objects and methods. By following best practices and utilizing enums effectively, developers can improve their code quality and workflow.


Best Practices for Using Enums in CSharp

When using enums in CSharp, there are certain best practices that can help maintain code readability and organization. Here are some tips for using enums efficiently:

  • Make the enum values descriptive: Using descriptive names for enum values can make the code more readable and easier to understand.
  • Use singular naming conventions: Using a singular naming convention can help make the code consistent and more intuitive.
  • Use implicit casting for simple types: Implicit casting can be used to avoid explicit cast statements. This makes the code easier to read and reduces the risk of errors.
  • Organize enums logically: To make the code easier to read and understand, organize enums logically. For example, group related enums together in the same code file.
  • Be careful when altering enum values: Altering the values of enums can break compatibility with existing code. If an enum value needs to be updated, consider creating a new enum instead.
  • Avoid using enums with a large number of values: Enums with a large number of values can negatively impact performance. Consider using alternative solutions, such as a lookup table or a database table.
  • Use enums in switch statements: Switch statements with enums can be more intuitive and easier to read than using if statements. However, be careful to avoid common pitfalls, such as not including a default case.

By following these best practices and recommended coding patterns, developers can make the best use of enums in CSharp and produce maintainable, organized code.


Enum Limitations

Enums can be incredibly useful for providing a set of related constant values in your code. However, there are some limitations worth noting.

  • Firstly, enums do not lend themselves well to extensibility. This means that once you’ve defined an enum, it’s compiled to be that set (i.e. not a dynamic collection/mapping). This limitation can present problems in situations where you may want to add new enum values at runtime. But while this may not even be a concern for you, the bigger challenge/risk is when modifying the set of enum values. This can break all of the consuming locations in your code and cause a maintenance headache.
  • Secondly, enums can’t contain duplicate values. In some cases, you might want to have multiple enum values that represent the same underlying value. For example, you might want to have an enum for different HTTP status codes, where both “not found” and “resource not found” map to the same value. With enums, you would have to choose one of those values and exclude the other.

If you’re concerned you’re not using enums in C# properly, then check out this video:

YouTube player

Enum Alternatives

Fortunately, there are alternatives to using enums when they may not be the best fit for your needs. One alternative is to use a class with constant fields. This provides the same constant value behavior as an enum, but with the added flexibility of being extensible and allowing for duplicate values.

Another alternative is to use a dictionary or lookup table to map values to their corresponding enums. This can help address the limitations of enums by allowing for duplicate values and easier extensibility.

It’s important to remember that while enums can be a useful tool in your programming toolbox, they may not always be the best solution for your specific needs. In those cases, exploring alternatives such as constant fields or mapping tables can be a valuable approach.


Wrapping Up Enums in CSharp

Enums are a useful tool in C# and dotnet programming. They simplify your codebase and make it easier to read and maintain. In this guide, we covered what enums are, how to declare them, and their specific use cases. We also covered how to use them with object-oriented programming paradigms and their limitations in some scenarios.

By utilizing the tips and best practices provided in this guide, readers can unlock the full potential of C# with enums. It is essential to practice these techniques and keep learning to improve your programming skills continually. We hope that this guide has been informative and helpful to all readers looking to enhance their C# and dotnet programming abilities.

Don’t forget to subscribe to the Dev Leader Weekly newsletter and check out my YouTube channel for more tips and guidance on C# programming!

Affiliations:

These are products & services that I trust, use, and love. I get a kickback if you decide to use my links. There’s no pressure, but I only promote things that I like to use!

      • RackNerd: Cheap VPS hosting options that I love for low-resource usage!
      • Contabo: Alternative VPS hosting options with very affordable prices!
      • ConvertKit: This is the platform that I use for my newsletter!
      • SparkLoop: This service helps me add different value to my newsletter!
      • Opus Clip: This is what I use for help creating my short-form videos!
      • Newegg: For all sorts of computer components!
      • Bulk Supplements: For an enormous selection of health supplements!
      • Quora: I try to answer questions on Quora when folks request them of me!

    author avatar
    Nick Cosentino Principal Software Engineering Manager
    Principal Software Engineering Manager at Microsoft. Views are my own.

    Leave a Reply