Working with Enums in C#

Just wanted to share a helper class I’m using in some projects to make it easier to work with enums.

    public static class EnumHelpers
    {
        private const string MustBeAnEnumeratedType = @"T must be an enumerated type";

        public static T ToEnum<T>(this string s) where T : struct, IConvertible
        {
            if (!typeof (T).IsEnum) throw new ArgumentException(MustBeAnEnumeratedType);
            T @enum;
            Enum.TryParse(s, out @enum);
            return @enum;
        }

        public static T ToEnum<T>(this int i) where T : struct, IConvertible
        {
            if (!typeof (T).IsEnum) throw new ArgumentException(MustBeAnEnumeratedType);
            return (T) Enum.ToObject(typeof (T), i);
        }

        public static T[] ToEnum<T>(this int[] value) where T : struct, IConvertible
        {
            if (!typeof (T).IsEnum) throw new ArgumentException(MustBeAnEnumeratedType);
            var result = new T[value.Length];
            for (int i = 0; i < value.Length; i++)
                result[i] = value[i].ToEnum<T>();
            return result;
        }

        public static T[] ToEnum<T>(this string[] value) where T : struct, IConvertible
        {
            if (!typeof (T).IsEnum) throw new ArgumentException(MustBeAnEnumeratedType);
            var result = new T[value.Length];
            for (int i = 0; i < value.Length; i++)
                result[i] = value[i].ToEnum<T>();
            return result;
        }

        public static IEnumerable<T> ToEnumFlags<T>(this int i) where T : struct, IConvertible
        {
            if (!typeof (T).IsEnum) throw new ArgumentException(MustBeAnEnumeratedType);
            return
                (from flagIterator in Enum.GetValues(typeof (T)).Cast<int>()
                    where (i & flagIterator) != 0
                    select ToEnum<T>(flagIterator));
        }

        public static bool CheckFlag<T>(this Enum value, T flag) where T : struct, IConvertible
        {
            if (!typeof(T).IsEnum) throw new ArgumentException(MustBeAnEnumeratedType);
            return (Convert.ToInt32(value, CultureInfo.InvariantCulture) & Convert.ToInt32(flag, CultureInfo.InvariantCulture)) != 0;
        }

        public static IDictionary<string, T> EnumToDictionary<T>() where T : struct, IConvertible
        {
            if (!typeof (T).IsEnum) throw new ArgumentException(MustBeAnEnumeratedType);
            IDictionary<string, T> list = new Dictionary<string, T>();
            Enum.GetNames(typeof (T)).ToList().ForEach(name => list.Add(name, name.ToEnum<T>()));
            return list;
        }

The first ToEnum extension allows you to write something like this:

"Value1".ToEnum<MyEnum>()

It adds a ToEnum method to the string class in order to convert a string to an enum value.

The second ToEnum extension does the same but with ints e.g.:

0.ToEnum<MyEnum>()

The third ToEnum extension is similar but extends int arrays to return a collection of enum values e.g.:

new[] {1, 0}.ToEnum<MyEnum>()

The forth ToEnum extension does the same but with string arrays e.g.:

new[] {"Value2", "Value1"}.ToEnum<MyEnum>()

The ToEnumFlags extension returns a list of enum values when working with flags e.g.:

13.ToEnumFlags<MyEnum2>().Select(e => e.ToString()).Aggregate((e, f) => (e + " " + f))

The EnumToDictionary method returns a dictionary with the enum item name as key and values e.g.:

EnumHelpers.EnumToDictionary<MyEnum>()["Value2"]

The CheckFlag extension converts checks whether an enum flag is set e.g.:

(MyEnum2.Flag1 | MyEnum2.Flag4).CheckFlag(MyEnum2.Flag4)

To test this you can use the following:

    internal enum MyEnum
    {
        Value1,
        Value2,
    }

    [Flags]
    internal enum MyEnum2
    {
        Flag1 = 1,
        Flag2 = 2,
        Flag3 = 4,
        Flag4 = 8,
    }

    public static class MainClass
    {
        public static void Main()
        {
            Console.WriteLine("1) {0}", (int) "Value1".ToEnum<MyEnum>());
            Console.WriteLine("2) {0}", 0.ToEnum<MyEnum>());
            Console.WriteLine("3) {0}", new[] {1, 0}.ToEnum<MyEnum>());
            Console.WriteLine("4) {0}", new[] {"Value2", "Value1"}.ToEnum<MyEnum>());
            Console.WriteLine("5) {0}", 13.ToEnumFlags<MyEnum2>().Select(e => e.ToString()).Aggregate((e, f) => (e + " " + f)));
            Console.WriteLine("6) {0}", (int) EnumHelpers.EnumToDictionary<MyEnum>()["Value2"]);    
            Console.WriteLine("7) {0}", (MyEnum2.Flag1 | MyEnum2.Flag4).CheckFlag(MyEnum2.Flag4));
            Console.WriteLine("8) {0}", (MyEnum2.Flag1 | MyEnum2.Flag4).CheckFlag(MyEnum2.Flag3));
        }
    }

which will output:

1) 0
2) Value1
3) Playground.MyEnum[]
4) Playground.MyEnum[]
5) Flag1 Flag3 Flag4
6) 1
7) True
8) False

I guess most methods are pretty basic but sometimes it’s easier to just have a helper class and not have to think about how to solve the problem again and again (even though it’s not a very complex problem)…

Leave a Reply

Your email address will not be published. Required fields are marked *