如何避免使用枚举?

Posted

技术标签:

【中文标题】如何避免使用枚举?【英文标题】:How to avoid using Enums? 【发布时间】:2011-01-17 03:07:00 【问题描述】:

直到在这里询问question 之前,我从未认为(枚举)是“坏事”。对于那些认为它们不是最佳实践的人,有哪些方法/模式可以避免在代码中使用它们?

编辑:

public Enum SomeStatus
 Approved = 1
 Denied = 2
 Pending =3
end Enum

【问题讨论】:

嗯...强类型枚举是件好事吗? (是) 澄清一下,“枚举”是指枚举类型,而不是使用 IEnumerable 接口来表示序列。 有人告诉我,他们在类之间创建了耦合和依赖关系...... 我觉得你的问题太含糊了。枚举类型,就像几乎所有其他编程概念一样,有好的和坏的用途。它们在某些情况下是坏事,而对另一些情况则是好事。你能说得更具体点吗? 我想知道这是否是 SOLID 社区中的人们可能会详细说明的内容? 【参考方案1】:

枚举的问题在 Fowler 的 Refactoring 中进行了描述,其中它被认为是代码异味。它与类型安全无关,而是迫使您在整个代码中散布switch 语句,从而违反了DRY 原则

State pattern 是相同结构的更好模型,因为它允许您在同一类中实现和更改与同一状态相关的逻辑。这也增加了凝聚力并减少了类耦合。

【讨论】:

@ploeh 在 2005 年版的 Fowler 重构中撤回了这一判断。【参考方案2】:

我认为使用枚举是一件好事。它提供了强大的类型安全性。

它们有时有一些缺点,但这通常与事先不知道所有可能选项的情况有关。如果您有一组固定的选项,例如您的示例,那么强类型枚举是一件好事,不应避免。

【讨论】:

实际上在这种情况下应该使用它们,而不是到处硬编码 1、2 和 3。 是的,提供一定程度的安全性和理解力,您不会使用“幻数”。 但要注意它们实际上并没有提供类型安全,除了强制值是枚举的基础类型的类型。 status = (SomeStatus)8374 可以正常编译和运行,但可能会破坏您的代码。 @Kent:非常正确,但它仍然比仅使用数字更安全,因为(没有强制转换)编译器会进行一些检查。也更易于维护,因为名称很明确。 @onof 这完全取决于相关应用程序。对于许多系统,都有固定的选项集。【参考方案3】:

我喜欢乌龟 class enums。

【讨论】:

【参考方案4】:

枚举的要点是它只在一个地方定义(数据库术语中的规范化)。如果这个枚举是你正在编写的类的合法部分,那么继续。

否则,特别是如果您发现自己多次声明它,请重新考虑您的枚举的用途。它真的携带数据吗?是否有足够的值来考虑将可能性存储在数据库中?

【讨论】:

【参考方案5】:

我喜欢将易于使用和理解的名称放在相关值集上的枚举。我只是不喜欢 c# 实现。使用您的示例枚举:

SomeStatus status = 17;

即使 17 超出范围,也可以毫无问题地编译和运行。

Delphi 有更好的枚举(或者至少,它曾经是——我已经有好几年没有使用它了)

【讨论】:

您能否详细说明“17 已超出范围”? 枚举中指定的值是 1、2 和 3。但是,像我的示例这样的变量将采用任何整数值,无论它是否是枚举中的有效值。我认为这消除了枚举的类型安全方面。 我不同意 17 在所有情况下都是无效的枚举。我相信这就是您所说的,因为您不喜欢 C# 实现。如果一组状态类型值是从外部源定义的,而我们不关心应用程序中的值 4-16 怎么办?在这种情况下,17 可能是一个完全有效的枚举值。在我最近开发的一个应用程序中,我们有大量构成语言资源的枚举,并且希望将枚举值分组以使代码清晰。因此,我们指定了数百个组,其中可能只使用 100-157 的值,而不是跳到 200 用于下一个组。 这没有错 - 但在问题的示例枚举中,值是 1、2、3。没有 17。所以 17 对此应用程序无效。如果需要 17,则可以声明枚举包括 1、2、3、17。 17 有效,但 16 和 18(以及任何其他数字)无效。 IMO,如果您需要使用不属于声明的枚举的值,那么您不应该使用枚举。

以上是关于如何避免使用枚举?的主要内容,如果未能解决你的问题,请参考以下文章

我应该如何最好地模拟和/或避免 Python 中的枚举? [复制]

在结构中使用 typedef 枚举并避免类型混合警告

SpriteKit:如何添加/删除节点并避免枚举时出现突变异常?

如何获得 Swift 枚举的计数?

C#资源文件和C#枚举如何结合使用?

对参数使用 IReadOnlyCollection<T> 而不是 IEnumerable<T> 以避免可能的多次枚举