Using Enums in .NET APIs

Using enums in API has been a debatable topic for as long as I can remember. Some developers are completely against them and they resort to custom types or simply consts and some cannot look away from the facilities that comes with them. In this blog post I am going to show some out-of-the-box ways to facilitate using enum types in APIs and leave the debates to the reader.

If you use enums in an API, there’s a good chance you will have to convert from and to strings.

Converting enum to string

Enum has a static method that accepts the type of an enum, plus the value and returns the name of that value as string.

public static string GetName(Type enumType, object value)

Example:

public enum AgeGroup
{
  Infant,
  Kid,
  Adult
}

var test = AgeGroup.Infant;

// This would print "Infant".
Consule.WriteLine(Enum.GetName(typeof(AgeGroup), test);

Extracting all enum names

There is another out-of-the-box method in the Enum type GetNames that you can use to get the names of all members of an enum type, but to make it easier to use that method you can write a utility method. I will give you an example, but it can be written in different styles of course.

public class EnumUtility<T> where T : Enum
{
    public static string GetCommaDelimitedNames() => Enum.GetNames(typeof(T)).ToCommaDelimitedString();
}

You can use easily use this method like the following example.

EnumUtility<MyEnum>.GetCommaDelimitedNames();

Converting string to enum

Enum has a static method that accepts the name of an enum item in string and outputs the enum equivalent if possible.

public static bool TryParse<TEnum>(string value, out TEnum result) where TEnum : struct

The interesting part, is that this method follows the try pattern and returns true on success, so you can easily use it in an if block and mix it with your validation logic. Lets see an example.

public enum AgeGroup
{
  Infant,
  Kid,
  Adult
}

if (Enum.TryParse("Kid", out AgeGroup output))
{
  // Success
}
else
{
  // Failure3
  throw new InvalidOperationException("Invalid value has been given. Valid values are: " + EnumUtility<AgeGroup>.GetCommaDelimitedNames();
}

Boosting performance

The GetName method uses reflection internally to extract the name of an enum member and depending on the use case it can have a dent in the performance of your API. One trick you can do to boost the performance is to permanently cache all members of your enum in a dictionary and rely on the dictionary to look up the names. You can load this dictionary when your API starts. In this case you will be trading memory for CPU cycles which in this cases seems to be a fair deal.


Posted

in

by

Tags:

Comments

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: