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<MyEnumType> enumvals = new List<MyEnumType>();
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<T> GetListOfEnum<T>() {
Type t = typeof(T);
if ( !t.IsEnum ) {
throw new ArgumentOutOfRangeException( t.FullName + " is not an Enum" );
}
Array vals = Enum.GetValues( t );
List<T> enumvals = new List<T>();
foreach ( T val in vals ) {
enumvals.Add( val );
}
return enumvals;
}
Call it like this:
List<MyEnum> vals = ExtensionMethodClass.GetListOfEnum<MyEnum>();
(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 1/2 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<T> GetListOfEnum<T>() {
Type t = typeof(T);
if ( !t.IsEnum ) {
throw new ArgumentOutOfRangeException( t.FullName + " is not an Enum" );
}
return Enum.GetValues( typeof(T) ).Cast<T>().ToList();
}
Now that's pretty compact! Nice.
Rob