枚举和case语句

本文关键字:语句 case 枚举 | 更新日期: 2023-09-27 18:12:03

我正在寻找好的理由,如果我们应该尝试避免switch/case语句,以及如何为枚举做到这一点,并建议如何,考虑以下示例:(注意,这个switch/case可能分散在整个代码库中)

switch (theEnum)
{
    case MyEnum.Enum1:
        // dosomething
    case MyEnum.Enum2:
        // do something
    case MyEnum.Enum3:
        // do something
    default:
       throw new Exception("Unsupported enumeration: " + theEnum.ToString());

}

public Dictionary<MyEnum, StrategyBase> BuildMapper()
{
    var mapper = new Dictionary<MyEnum, StrategyBase>();
    mapper[MyEnum.Enum1] = new Strategy1();
    mapper[MyEnum.Enum2] = new Strategy2();
    mapper[MyEnum.Enum3] = new Strategy3();
return mapper;
}
BuildMapper()[MyEnum.Enum1].DoSomething();

选项2更面向对象,但我想知道其他人对这种方法的看法,以及我们是否应该努力这样做是否有好的和令人信服的理由。

有人可能会说像switch/else这样的原则会违反开闭规则。

枚举和case语句

对于OO,您应该使用访问者模式

我会将BuildMapper设置为静态(以及只读),因为它将始终返回相同的Dictionary集。

至于为什么这是好的,原因应该很简单,当你有一个从一个东西映射到另一个东西的设计,这个映射总是静态的,很明显,将它表示为字典,而不是if/else或switch case,这隐藏了它只是一个映射的意图。

如果只是在一两个地方,我会选择切换。如果,正如您所说,"这个开关/情况可能分散在整个代码库中",那么请使用第二种解决方案。

它不仅更加面向对象,这很好,而且在您的情况下更容易维护。在这种情况下,对性能和内存消耗的关注是完全无关的,首先要考虑维护的便利性,并在需要时进行优化(但我认为您永远不需要优化这个)。在这种情况下,可读性损失也无关紧要——理解第二种方法的作用只需要很少的时间。

我认为第一个变体更好,因为它看起来更可读,更明确。

我想说,这一切都归结于你想要实现的目标。第一个示例更容易阅读,如果您与其他人共享代码库,这一点很重要。如果您要遵循某些模式

,则BuilderMapper可能很有用。

我猜你是在比较橙子和苹果。

开关是一个变量和几个常量数据之间的顺序比较。除非您有一个1k大小写开关,否则它应该比Dictionary性能好得多。

当然,与Dictionary这样相当复杂的对象相比,switch消耗的内存要少得多。

最后,枚举不局限于声明的选项,但可以组合为"标志"。使用hashmap将无法使用此功能。

满意吗?