关于c:是否可以迭代枚举中的每个选项?

Is it possible to iterate through each choice in an enum?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
How to enumerate an enum?

所以我有一些这样的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
enum Decision
{
  DecisionA,
  DecisionB,
  ...
}

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

基本上,无论决策是什么,DoStuff都会做同样的事情,但决策是用来使它做的事情更为优化(更快或更为理想)。

现在,我想为dostuff实现单元测试。通过拥有一个类似于new Decision[]{DecisionA, DecisionB, ...};的数组来测试所有决策是否正常工作是相当容易的,但是,如果我添加了一个决策,那么我必须返回并手动将其添加到单元测试中。

是否可以访问enum指定的所有可能选项?例如,如下所示:

1
2
3
4
foreach(var d in Decision.Options)
{
  //d will be DecisionA, and then DecisionB, etc etc
}

你可以使用Enum.GetValues,但我个人并不喜欢。您需要强制转换(例如通过指定迭代变量类型),并通过typeof提供类型:

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

我更喜欢我在无约束旋律中提供的选项-一个提供枚举和委托扩展方法的小库:

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

这是:

  • 返回类型中的类型安全(它返回一个IList)
  • 类型参数中的类型安全(类型必须是枚举)
  • 更高效,因为它对所有调用重复使用相同的只读列表

当然,这意味着使用一个额外的库…对于您来说,单次调用可能不值得,但是如果您使用Enums做了很多事情,您可能会发现其他功能很有用。


可以使用System.Enum.GetValues。


乔恩的答案给了你枚举,这里还有一些随机的东西…

对于测试来说,最好换一种方式——确保值列表(Enum.GetValues与测试中的硬编码列表匹配。当您添加新值时使测试失败,然后更新测试以对新值做一些明智的事情(如果对不同情况的测试实际需要不同,则很有用)。

另一种看待它的方法是:switchif的链不是控制代码流的最佳构造。您可以使用多态性或简单的字典来重构它,使其更具可测试性/可扩展性(几个问题,如如何重构这个巨大的switch语句?).