【问题标题】:Is it possible to iterate through each choice in an enum? [duplicate]是否可以遍历枚举中的每个选择? [复制]
【发布时间】:2012-11-10 00:08:40
【问题描述】:

可能重复:
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
}

【问题讨论】:

    标签: c# .net unit-testing enums


    【解决方案1】:

    您可以使用Enum.GetValues,但我个人不是这样的超级粉丝。您需要强制转换(例如,通过指定迭代变量类型),并通过 typeof 提供类型:

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

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

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

    这是:

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

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

    【讨论】:

    【解决方案2】:

    您可以使用System.Enum.GetValues

    【讨论】:

      【解决方案3】:

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

      对于测试,换一种方式可能是更好的方法 - 确保值列表 (Enum.GetValues) 与测试中的硬编码列表匹配。添加新值时使测试失败,然后更新测试以对新值执行一些明智的操作(如果针对不同情况的测试实际上需要不同,则很有用)。

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

      【讨论】:

      • 我不使用枚举的问题是有时“决定”是基于随机数生成器。将 int 转换为枚举很容易。获取一个 int 并让它调用一个或另一个函数是一个更大的痛苦
      • @Earlz,Dictionary&lt;int, Func&lt;RType&gt; &gt; 之类的东西可能会起作用...如果它使 您的 代码更具可读性。
      猜你喜欢
      • 2015-08-13
      • 1970-01-01
      • 2021-04-01
      • 2011-06-14
      • 2023-03-03
      • 2013-04-05
      • 1970-01-01
      • 1970-01-01
      • 2011-11-28
      相关资源
      最近更新 更多