Get all Enum values as a List

Often times it’s helpful to get a list of all defined values for an enum.  Enum.GetValues(typeof(MyEnumType)) returns an Array.  This is less than helpful.  An untyped Array is harder to query against than something much more IQueriable<T>.

So I typically write something like this:

Type t = typeof(MyEnumType);
Array vals = Enum.GetValues(t);
List<string> enumvals = new List<string>();
foreach (T val in vals) {
    enumvals.Add(val);
}

After writing this code a dozen times, it occurred to me that an extension method was in order.  Here’s the extension method:

public static List GetListOfEnum<T>() {
    Type t = typeof(T);
    if (!t.IsEnum)
    {
        throw new ArgumentOutOfRangeException($"{t.FullName} is not an Enum");
    }

    Array vals = Enum.GetValues(t);
    List<string> enumvals = new List<string>();
    foreach (T val in vals)
    {
        enumvals.Add(val);
    }

    return enumvals;
}

Call it like this:

List vals = ExtensionMethodClass.GetListOfEnum<T>();

(yeah, since I didn’t have a this parameter, and didn’t really want to create a value to call an extension method, it’s really just a static method in some utility class.  That’s fine though.)

Ideally I’d like to say where T : Enum (so I’d get a compile error if I passed in a non-Enum T) but where specifically blocks Array, Delegate, Enum, ValueType, and object.  Rats.  Many have argued this should be allowed, but it isn’t.  Thus the check / throw at the top.  Some have suggested to use where T : struct or where T : IConvertable first to get 12 way there before the run-time check.  In the end, I suppose the answer is always the same: have good unit tests.

The last time I built this (non)extension method, ReSharper asked if it could help.  I said yes, and it turned it into this:

public static List GetListOfEnum<T>() {
    Type t = typeof(T);
    if (!t.IsEnum)
    {
        throw new ArgumentOutOfRangeException($"{t.FullName} is not an Enum");
    }
    return Enum.GetValues(typeof(T)).Cast().ToList();
}

Now that’s pretty compact!  Nice.