How to Convert a list of strings into a set of enums in C#

By FoxLearn 2/4/2025 4:36:38 AM   84
Imagine you have a list of user roles that you read from a configuration file or a database when your application starts. Whenever a user logs in, you want to check if their assigned role is part of the allowed roles list.

To optimize this, you can convert the list of roles into a HashSet<UserRole> for faster lookups.

To convert a string to an enum, you can use Enum.Parse(). For an entire list, the process would look like this:

new HashSet<UserRole>(userRoles.Select(s => Enum.Parse<UserRole>(s)));

In this article, I'll show you how to create a generic converter method that will help you filter out invalid values and make your code more robust.

Generic List<string> to HashSet<EnumT> Converter Extension Method

We'll create a generic converter extension method that:

  1. Converts a list of strings (representing enum values) into a set of enums.
  2. Filters out null, empty, or whitespace strings.
  3. Filters out invalid enum values.

You can easily customize the behavior of this converter; for example, you might choose to throw an exception if an invalid value is encountered, instead of simply filtering it out.

To build this converter, I added several unit tests. Here's an example test suite:

[TestClass()]
public class ListExtensionsTests
{
    [TestMethod()]
    public void TestToSet_HappyPath()
    {
        //arrange
        var list = new List<string>() { "Admin", "User", "Guest" };
        var expectedSet = new HashSet<UserRole>()
        {
            UserRole.Admin,
            UserRole.User,
            UserRole.Guest
        };

        //act
        var set = list.ToSet<UserRole>();

        //assert
        CollectionAssert.AreEquivalent(expectedSet.ToList(), set.ToList());
    }

    [TestMethod()]
    public void TestToSet_FiltersOutNullAndWhitespaceStrings()
    {
        //arrange
        var list = new List<string>() { "Admin", null, "", " " };
        var expectedSet = new HashSet<UserRole>()
        {
            UserRole.Admin
        };

        //act
        var set = list.ToSet<UserRole>();

        //assert
        CollectionAssert.AreEquivalent(expectedSet.ToList(), set.ToList());
    }

    [TestMethod()]
    public void TestToSet_FiltersOutInvalidEnumValues()
    {
        //arrange
        var list = new List<string>() { "SuperAdmin", "123" };
        var expectedSet = new HashSet<UserRole>()
        {
        };

        //act
        var set = list.ToSet<UserRole>();

        //assert
        CollectionAssert.AreEquivalent(expectedSet.ToList(), set.ToList());
    }
}

Now, we’ll implement the extension method that performs the conversion:

using System.Collections.Generic;
using System.Linq;

public static class ListExtensions
{
    public static HashSet<T> ToSet<T>(this List<string> values) where T : Enum
    {
        return new HashSet<T>(values.Where(s => !string.IsNullOrWhiteSpace(s)
            && Enum.IsDefined(typeof(T), s))
        .Select(s => (T)Enum.Parse(typeof(T), s)));
    }
}

In this example:

  • We use Enum.IsDefined() to check whether the string corresponds to a valid enum value.
  • The extension method only includes valid enum values and filters out null, empty, and invalid values.

For example, if a user role list contains SuperAdmin or an invalid number 123, these will be ignored because they're not part of the UserRole enum.

Here’s an example of how to use the extension method:

// Get the list of roles from a config or database
var list = new List<string>() { "Admin", "User", "Guest" };

// Convert the list to a set for fast lookup later
var userRoleSet = list.ToSet<UserRole>();

Console.WriteLine(string.Join(Environment.NewLine, userRoleSet));

If UserRole is defined as:

public enum UserRole
{
    Admin = 1,
    User = 2,
    Guest = 3
}

This will output:

Admin
User
Guest

This approach allows you to efficiently convert a list of strings into a set of valid enums, filtering out any invalid or irrelevant entries.