An enum (short for Enumeration) is a group of named constants in C# that represent fixed values. Enums can be used to create a set of named constants that can be referenced easily, making code more organized and readable. Enum values are integer-based, and every individual enum value has its unique integer equivalent. Learning how to use Enums in CSharp can be very helpful as they help developers write clean, maintainable code.
Understanding Enums is useful for software engineers because they provide a convenient mechanism to represent data, and doing so appropriately can lead to better and more efficient systems. By learning about enums, software engineers can ensure that their code is clean, organized, and easy to understand. Understanding how to use enums in CSharp also helps avoid their misuse!
Let’s dive into how to use enums in CSharp!
Core Concepts of Enums
In C#, enums or enumerations represent a set of named constants or values, similar to a regular variable, but with a predefined range of possible values. Enums are used to assign symbolic names to a set of constant values that will remain fixed throughout the program. This may allow for cleaner, more maintainable code and reduce the chance of coding errors. If we use them properly!
And to help you out, alongside this article, I put together this video on the basics for how to use enums in CSharp:
Declaration and Initialization of Enums
To declare an enum, begin with the enum
keyword, followed by the name of the enum, and then a set of constant values enclosed in curly brackets. A comma separates each value, and a semicolon is used to terminate the list. Below is an example of an enum for days of the week:
enum DaysOfWeek
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
};
To initialize and assign a value to an enum variable, reference the name of the enum value. For example, to initialize an enum variable for Monday, we would use:
DaysOfWeek currentDay = DaysOfWeek.Monday;
Sign up for Dev Leader Weekly!
Enum Members and Values
Each enum member has an automatically assigned integer value; by default, the integer values start at zero and increment by 1, but you can specify any valid integral value explicitly. In the example enum above, Monday is assigned the value 0, Tuesday 1, and so on. This behavior can be changed by using an equal sign and specifying the value of the member. For example:
enum DaysOfWeek
{
Monday = 1,
Tuesday = 2,
Wednesday = 3,
Thursday = 4,
Friday = 5,
Saturday = 6,
Sunday = 7
};
In the explicit value initialization above, Monday is now assigned the value 1, not 0, Tuesday is 2, and so on.
Using Enums in Switch Statements
Using switch statements to evaluate the value of an enum variable can make your code much more efficient, readable, and maintainable. Below is an example of using a switch statement to determine the current day of the week:
switch (currentDay)
{
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;
}
And sure, I get it. The example above isn’t stellar because the actual string value representing the name of the enum is what we want printed out. But it’s important to keep in mind the names of your enums are not always going to be exactly end-user-friendly. And if you still don’t want to believe me, just consider a situation
ToString and Back Again
This is a fun one, considering an enum gives us what appears to be a string representation and a numerical representation. The reality is, it’s purely numerical but we have readability as developers. But… it often leads us to want to go back and forth between numeric and string values.
While there are some obvious things we can do, including built-in static methods on the Enum class to get names, there are conflicting opinions on the best ways to go about this. I guess we shouldn’t be shocked at this point that people on the Internet disagree! Here’s a Stack Overflow conversation about string representations of enums – look at the variety!
What’s the *best* way? I don’t believe in universal bests. So have a skim through that and see if there are variations that suit your needs since each will have pros and cons. I’m happy to discuss your thoughts in the comments! You can watch this video on string parsing for some basic examples:
Limitations of Enums
Although enums can make your code cleaner and more maintainable, they also come with limitations. One major issue with enums is the fact that they have a fixed set of possible values. This means that, once the enum is defined, you cannot add or remove values from the enum without modifying the entire codebase.
In addition, enums are not typesafe, making them inherently more prone to errors than other data types. Even if your enum range had four entries with values 0, 1, 2, 3, you’re totally able to cast the value 123 to the enum and it just… works? Finally, enums can only be used with integral types, which can be limiting in certain scenarios.
To avoid issues arising from these limitations, it’s important to carefully consider the use of enums in particular scenarios, especially in larger projects where maintainability is a concern. However, with proper usage, enums can be an incredibly powerful tool in C# programming.
Best Practices for How to Use Enums in CSharp
As with any programming concept, there are several best practices associated with using enums effectively. In this section, we’ll go over some of the top best practices for enums in C# that’ll help you write clean and quality code.
Naming Conventions for Enums
When it comes to naming enums, it’s essential to use meaningful and descriptive names that convey the values they represent. It’s a best practice to name your enums in the singular form and begin them with a capital letter.
enum Color { Red, Green, Blue }
We’ll see a little bit later a variation of enums called “flags”, and naming these as plural is generally considered to be the best practice.
Initialization of Enum Values
Enum values are automatically assigned, starting at zero and then and then incrementing by one, based on their order. That is, the very first enum entry defined will have a numeric value of zero, the next one, and so on. You can also assign your own values explicitly to enums by using an assignment directly in the declaration:
enum DaysOfWeek { Monday = 1, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday };
Tips for Using Enums in Switch Statements
Using a switch statement with an enum variable as an argument can be a powerful way to write focused code. However, it’s essential to include a default case for the switch statement to handle unexpected input.
switch (day)
{
case DayOfWeek.Monday:
Console.WriteLine("Today is Monday.");
break;
case DayOfWeek.Tuesday:
Console.WriteLine("Today is Tuesday.");
break;
default:
Console.WriteLine("Invalid input.");
break;
}
Pitfalls in Using Enums
While using enums comes with a ton of benefits, it’s essential to be cautious of some associated pitfalls to avoid issues in your code. One of the primary pitfalls of using enums is that enums can become unwieldy, cluttered, and difficult to maintain if they’re not correctly organized or categorized. I believe one of the root causes of this is using enums to define a non-fixed collection of things.
If we take, for example, something like the days of the week – this is fixed. We have 7 total days in a week. Representing this with an enum means that we have a total of 7 states to be defined and this will be fixed in place. You may have state machines with a fixed number of states as well. However, if you are using enums to create a list of things that can continue to grow… you’re probably going to run into some headaches.
Consider all of the spots in your codebase that are trying to handle all of the cases for enum values. Sure, you can use else blocks and switch statements with a default so things don’t just explode… but does that actually guarantee the expected behavior? If you can continue to modify enums by extending them, the side effect is that all of the spots consuming the enum need some consideration.
Try to ask yourself if your enum represents a finite number of things. If not – an enum may not be the right tool for you, even if it feels like having a string/integer mapping is convenient. This video should help guide you through some considerations with Enum usage:
Advanced Features of Enums in C#
Enums in C# have advanced features as well, which provide more flexibility and power to developers. In this section, we explore some of these advanced features.
Combining Enums
Sometimes, we may need to combine two or more enums in C#. This can be achieved with the “Flags” attribute. It allows us to assign multiple values to a single variable. With respect to naming conventions for flag-enums, it’s generally considered best practice to be of plural form.
To use the “Flags” attribute, we need to declare it before the enum:
[Flags]
enum MyCustomEnumOptions
{
Option1 = 1,
Option2 = 2,
Option3 = 4,
Option4 = 8
}
Here, we have declared an enum with four options and each option has a value that is a power of two. If we want to combine Option1 with Option2, we can do it like this:
MyCustomEnumOptionsoptions =
MyCustomEnumOptions.Option1 |
MyCustomEnumOptions.Option2;
Check out this video to see more details on how flag Enums work:
Using Attributes in Enums
Attributes can be used with enums just like any other class or struct. We can set attributes on the enum as well as on individual members of the enum. We can use attributes to store metadata about the enum or its members.
Attributes can be used for many purposes, such as validation, documentation, and serialization. The following example demonstrates the usage of attributes with enums:
public enum PersonGender
{
[Description("Female")]
Female,
[Description("Male")]
Male,
[Description("Other")]
Other
}
Here, we set the Description attribute for each member to store how we want to present the data to the user. This attribute can then be used for validation or serialization purposes in the code.
Using these advanced features of enums can significantly enhance the power and flexibility of our C# code.
Benefits of Using Enums in C#
If you’ve enjoyed this article so far, continue reading about the benefits of using enums and real-world use cases. If you want full exclusive articles and early access to videos sent to your inbox every weekend, subscribe to my FREE newsletter.
Top comments (0)