Categorizing enumeration values in C#

Published on 07 May 2019 by Perry. Reading time: 4 minutes.

An enumeration is a declaration of named numerical constants. It is an often used concise solution for implementing discrete values and it keeps source code readable and type safe. Unfortunately, enumeration values cannot be categorized by default.

Single enumeration

Enumeration values cannot be categorized without affecting the composition of the enumeration or writing source code for filtering the enumeration values. Let me explain this by an example (demo1).

 

Categorizing enumeration values in C# 1

 

In this demo I have created an enumeration with food items which are written to the console output using a simple foreach loop.

 

Categorizing enumeration values in C# 2

 

But what if we only want to show the Italian, Mexican or vegetarian food items?

We can split the current enumeration into separate enumerations, but when we need combined food items we would have to make new enumerations (which means that enumeration values will have to be defined in multiple enumerations) or implement a custom method with business logic for all enumeration values (which must be changed in case the enumeration changes).

In this blog I will provide a reusable solution for maintaining a single enumeration which can be categorized.

Source code is created using Visual Studio 2019, runs on .NET Core 2.2. and can be found on GitHub.

 

Attribute base class

First, we need to add categories to the enumeration values. Categories can be added in a declarative way by using attributes. In the next demo (demo2), we start by defining an Italian, Mexican and Vegetarian custom attribute class. Each class is derived from the Attribute base class. After we have defined these attribute classes, we can add them to the enumeration values.

 

Categorizing enumeration values in C# 3

 

Now we must retrieve the enumeration values based on a given attribute class. This is done by the GetEnumValues method. In this method, the System.Reflection namespace is used for retrieving the MemberInfo of each enumeration value. The MemberInfo contains member metadata and is passed into the Attribute.IsDefined method to check whether the MemberInfo contains the requested attribute class type. If so, the enumeration value is added to a list of enumeration values that is returned as output of the GetEnumValues method.

 

Categorizing enumeration values in C# 4

 

The Main method calls the GetEnumValues method for each type of food to generate the console output.

 

Categorizing enumeration values in C# 5

 

Because the output of the GetEnumValues method is a list, LINQ functionality can be applied if needed.

 

Generics

The solution we have seen so far is working fine, but it only works for our Food enumeration. This is where generics comes in.

For this demo (demo3), I have first restructured  the project; enumerations in Enums.cs, categories in EnumAttributes.cs, GetEnumValues method in Utils.cs and Program.cs for writing the console output. I have also added the AttributeUsage attribute with value AttributeTargets.Field to the categories to minimize misuse. And although enumerations and categories are in separate files, they are both part of the Enums partial class. The main difference here is the implementation of generics for the GetEnumValues method.

 

Categorizing enumeration values in C# 6

 

The GetEnumValues method must be called using two class types; a type called TEnum for the source enumeration type and a type called TAttrib for the filter attribute class type. The where clauses prevent the usage of other types. The TEnum and TAttrib types are used with the System.Reflection namespace in the same way as in previous demo. The output of the GetEnumValues method is a list of enumeration values of the same type as the source enumeration type.

For testing purposes, an enumeration called Car has been added with the Supercar attribute.

 

Categorizing enumeration values in C# 7

 

With all this in place, the Main method can now call the GetEnumValues method for different enumeration types and attribute class types.

 

Categorizing enumeration values in C# 8

 

Categorizing enumeration values in C# 9

 

And that’s it: a reusable solution for maintaining a single enumeration which can be categorized by using the Attribute base class, System.Reflection and generics.

Tags: Overig

Perry

Published by Perry on 07 May 2019

In short; developer in his mid-forties, living in Alphen aan den Rijn (The Netherlands), married with Carola and has two awesome kids named Martijn and Jeroen. At young age I was fascinated by the possibilities of my first computer; a Commodore 16 with no less than 16 KB RAM. After getting my degree in electrical engineering I first started programming PLC’s for process automation. After a couple of years I gradually entered the world of Microsoft software development starting with Visual Basic 3.0 and Visual InterDev 6.0 as development environment. In recent years I have focussed on Azure technologies. I like to experiment with new technologies and solve complex issues with simple solutions.

 

Comments? Share them below

Learn more about ETTU

And the way we work