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 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 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.