How can you enumerate an enum
in C#?
E.g. the following code does not compile:
public enum Suit
{
If enum values range strictly from 0 to n - 1, a generic alternative is:
public void EnumerateEnum<T>()
{
int length = Enum.GetValues(typeof(T)).Length;
for (var i = 0; i < length; i++)
{
var @enum = (T)(object)i;
}
}
If enum values are contiguous and you can provide the first and last element of the enum, then:
public void EnumerateEnum()
{
for (var i = Suit.Spade; i <= Suit.Diamond; i++)
{
var @enum = i;
}
}
But that's not strictly enumerating, just looping. The second method is much faster than any other approach though...
You won't get Enum.GetValues()
in Silverlight.
Original Blog Post by Einar Ingebrigtsen:
public class EnumHelper
{
public static T[] GetValues<T>()
{
Type enumType = typeof(T);
if (!enumType.IsEnum)
{
throw new ArgumentException("Type '" + enumType.Name + "' is not an enum");
}
List<T> values = new List<T>();
var fields = from field in enumType.GetFields()
where field.IsLiteral
select field;
foreach (FieldInfo field in fields)
{
object value = field.GetValue(enumType);
values.Add((T)value);
}
return values.ToArray();
}
public static object[] GetValues(Type enumType)
{
if (!enumType.IsEnum)
{
throw new ArgumentException("Type '" + enumType.Name + "' is not an enum");
}
List<object> values = new List<object>();
var fields = from field in enumType.GetFields()
where field.IsLiteral
select field;
foreach (FieldInfo field in fields)
{
object value = field.GetValue(enumType);
values.Add(value);
}
return values.ToArray();
}
}
Three ways:
Enum.GetValues(type)
// Since .NET 1.1, not in Silverlight or .NET Compact Frameworktype.GetEnumValues()
// Only on .NET 4 and abovetype.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null))
// Works everywhereI am not sure why GetEnumValues
was introduced on type instances. It isn't very readable at all for me.
Having a helper class like Enum<T>
is what is most readable and memorable for me:
public static class Enum<T> where T : struct, IComparable, IFormattable, IConvertible
{
public static IEnumerable<T> GetValues()
{
return (T[])Enum.GetValues(typeof(T));
}
public static IEnumerable<string> GetNames()
{
return Enum.GetNames(typeof(T));
}
}
Now you call:
Enum<Suit>.GetValues();
// Or
Enum.GetValues(typeof(Suit)); // Pretty consistent style
One can also use some sort of caching if performance matters, but I don't expect this to be an issue at all.
public static class Enum<T> where T : struct, IComparable, IFormattable, IConvertible
{
// Lazily loaded
static T[] values;
static string[] names;
public static IEnumerable<T> GetValues()
{
return values ?? (values = (T[])Enum.GetValues(typeof(T)));
}
public static IEnumerable<string> GetNames()
{
return names ?? (names = Enum.GetNames(typeof(T)));
}
}
A simple and generic way to convert an enum to something you can interact:
public static Dictionary<int, string> ToList<T>() where T : struct
{
return ((IEnumerable<T>)Enum
.GetValues(typeof(T)))
.ToDictionary(
item => Convert.ToInt32(item),
item => item.ToString());
}
And then:
var enums = EnumHelper.ToList<MyEnum>();
foreach (Suit suit in (Suit[]) Enum.GetValues(typeof(Suit)))
{
}
Note: The cast to (Suit[])
is not strictly necessary, but it does make the code 0.5 ns faster.