是否有可能在枚举中迭代每个选项?

时间:2012-11-21 17:06:25

标签: c# .net unit-testing enums

  

可能重复:
  How to enumerate an enum?

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

enum Decision
{
  DecisionA,
  DecisionB,
  ...
}

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

基本上DoStuff,无论做出什么决定,都会做同样的事情,但是决定用来做出更优化的事情(更快或更好)。

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

是否可以只访问enum指定的所有可能选项?例如,像这样:

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

3 个答案:

答案 0 :(得分:10)

你可以使用Enum.GetValues,但就我个人而言,我并不是一个忠实的粉丝。你需要强制转换(例如通过指定迭代变量类型),并通过typeof提供类型:

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

我更喜欢Unconstrained Melody中提供的选项 - 一个在枚举和代理上提供扩展方法的小库:

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

这是:

  • 返回类型的类型安全(它返回IList<T>
  • 类型参数中的类型安全(类型必须是枚举)
  • 更高效,因为它为所有呼叫重用相同的只读列表

当然它确实意味着使用一个额外的库...它可能不值得你只为一个电话,但如果你用枚举做很多事情,你可能会发现其他功能有用

答案 1 :(得分:3)

您可以使用System.Enum.GetValues

答案 2 :(得分:1)

Jon的回答为您提供了枚举,这里有一些更随机的内容......

对于测试,可能是更好的方法 - 确保值列表(Enum.GetValues)与测试中的硬编码列表匹配。添加新值时使测试失败,然后更新测试以对新值做一些合理的事情(如果对不同情况的测试实际上需要不同,则非常有用)。

另一种查看它的方法 - switchif链不是控制代码流的最佳构造。您可以使用多态或简单字典重构它以使其更易于测试/扩展(像How to refactor this huge switch statement?这样的几个问题。)