Aug 14 2008
Foreaching in an enum’s values
This post is BS. Read the notes at the bottom or the comments.
Here’s a very short and self-explanatory snippet that you might find useful.
Suppose you have an enum, like one describing the different states that an actor can take :
public enum ActorState { Idle, Walking, Sliding, Jumping, Bouncing }
This list is subject to change, because you’re still writing your actor’s code and expanding its actions.
And somewhere in your code you need to loop in all those states, like for example to do a ListBox values list to choose from in your editor. You’d have to do that :
for (ActorState i = ActorState.Idle; i <= ActorState.Bouncing; i++) { // ... }
And this is a bad idea for two reasons :
- Whenever you add more actor states, you’ll have to change all your loops for them to see it.
- If you use bit flags or manually set values to your enum fields, you might miss enum fields when incrementing, or you’ll reach values that don’t correspond to any enum field.
A simple solution to these problems is to use this method :
public static IEnumerable<T> Enumerate<T>() where T : struct { foreach (object value in Enum.GetValues(typeof(T))) yield return (T)value; }
This will return an enumerable, typesafe/strongly-typed collection of enumeration vaules that will catch everyone of them. It’s used like so :
foreach (ActorState state in Util.Enumerate<ActorState>()) { // ... }
If you’re in C# 3.0, you can replace the “ActorState” loop variable declaration to a “var” and cut down on unnecessary code.
One problem with my method is that you can pass any struct, not just enums, and this will probably raise an exception. But hey, we’re all adults here,… garbage-in, garbage-out.
Oops…
As Brac suggested in the comments below, simply foreach’ing on what Enum.GetValues returns works just as well :
foreach (ActorState state in Enum.GetValues(typeof(ActorState))) { // ... }
I assumed (and I was pretty sure…) that this didn’t work since Enum.GetValues() returns an Array, which is not IEnumerable<T> so I thought it wouldn’t even compile. But it seems that implicit casting is done and it does work. Also it turns out that my combination of foreach and yield returns is too slow in time-critical sections.