4

可能重复:
如何枚举枚举?

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

enum Decision
{
  DecisionA,
  DecisionB,
  ...
}

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

基本上DoStuff,无论做出什么决定,都会做同样的事情,但该决定用于使其所做的事情更优化(更快或其他)。

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

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

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

3 回答 3

10

您可以使用Enum.GetValues,但我个人不是它的忠实拥护者。您需要进行强制转换(例如,通过指定迭代变量类型),并通过以下方式提供类型typeof

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

我更喜欢我在Unconstrained Melody中提供的选项——一个提供枚举和委托扩展方法的小库:

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

这是:

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

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

于 2012-11-21T17:07:46.570 回答
3

您可以使用System.Enum.GetValues

于 2012-11-21T17:07:49.697 回答
1

乔恩的回答给了你枚举,这里有一些更随机的东西......

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

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

于 2012-11-21T17:18:01.620 回答