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 enumvals = new List();
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() {
    Type t = typeof(T);
    if ( !t.IsEnum ) {
        throw new ArgumentOutOfRangeException( t.FullName + " is not an Enum" );
    }

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

    return enumvals;
}

Call it like this:

List vals = ExtensionMethodClass.GetListOfEnum();

(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() {
    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.

Rob