3

Possible Duplicate:
How to enumerate an enum?

So I have a bit of code like this:

enum Decision
{
  DecisionA,
  DecisionB,
  ...
}

public void DoStuff(Decision d)
{
  switch(d)
  {
    case Decision.DecisionA:
    ....
    ...
  }
}

Basically DoStuff, will do the same thing no matter what the decision, but the decision is used to make what it does more optimal(faster or whatever).

Now, I'd like to implement unit testing for DoStuff. It's fairly easy to test that all the Decisions work properly by having an array like new Decision[]{DecisionA, DecisionB, ...}; However, if I add a decision, I then have to go back and manually add it to the unit test.

Is it possible to just access all of the possible options specified by an enum? For instance, something like this:

foreach(var d in Decision.Options)
{
  //d will be DecisionA, and then DecisionB, etc etc
}
Community
  • 1
  • 1
Earlz
  • 57,517
  • 89
  • 275
  • 484

3 Answers3

10

You can use Enum.GetValues, but personally I'm not a huge fan of that. You'd need to cast (e.g. by specifying the iteration variable type), and provide the type via typeof:

foreach (Decision decision in Enum.GetValues(typeof(Decision)))
{
}

I prefer the option I made available in Unconstrained Melody - a little library providing extension methods on enums and delegates:

foreach (var decision in Enums.GetValues<Decision>())
{
}

This is:

  • Type-safe in return type (it returns an IList<T>)
  • Type-safe in type argument (the type has to be an enum)
  • More efficient as it reuses the same read-only list for all calls

Of course it does mean using an extra library... it may well not be worth it for you for just a single call, but if you're doing a lot of things with enums, you may find the other features useful.

Jon Skeet
  • 1,261,211
  • 792
  • 8,724
  • 8,929
3

You can use System.Enum.GetValues.

prprcupofcoffee
  • 2,900
  • 14
  • 19
1

Jon's answer gives you enumeration, here some more random things...

For tests it may be better way to go other way around - make sure that list of values (Enum.GetValues) matches to hard-coded list in the test. Make test fail when you add new values and then update test to do something sensible for new value (useful if testing for different case actually need to be different).

One more way to look at it - switch and chains of if is not necessary best construct to control the flow of code. You may be able to refactor using polymorphism or simple dictionary it to be more testable/extendable (several questions like How to refactor this huge switch statement? ).

Community
  • 1
  • 1
Alexei Levenkov
  • 94,391
  • 12
  • 114
  • 159
  • My problem with not using an enumeration is that sometimes the "decision" is based on a random number generator. Casting an int to an enum is easy. Taking an int and making it call one function or another is a much larger pain – Earlz Nov 21 '12 at 17:20
  • 1
    @Earlz, Something like `Dictionary >` may work... if it makes *your* code more readable. – Alexei Levenkov Nov 21 '12 at 17:26