为什么在枚举中使用位置标记(例如first或last)被认为是不良实践?

5
根据MSDN文档中System.Enum类的最佳实践部分所述:不要定义一个枚举值只是为了反映该枚举本身的状态。例如,不要定义一个标记枚举常量,仅表示枚举的结尾。如果需要确定枚举的最后一个值,请明确检查该值。此外,如果范围内的所有值都是有效的,则可以对第一个和最后一个枚举常量执行范围检查。如果我理解正确,我们不应将枚举声明为以下方式。
public enum DrawOrder
{
    VeryBottom = 0,
    Bottom = 1,
    Middle = 2,
    Top = 3,
    Lowest = VeryBottom, //marks a position in the enum
    Highest = Top, //marks a position in the enum
}

为什么这被认为是不好的实践?

1
我猜这是从C/C++延续下来的一种做法。在.NET世界中,我们有Enum.IsDefinedEnum.GetValues等等,所以这种hack已经不再有太多意义了。 - Todd Li
4个回答

2

我不确定我同意这是一种糟糕的实践;这取决于情况。

Steve McConnell的《代码大全》使用了这种结构。(这本书已经开始显示它所使用的语言过时了,因此这种技术可能在那时是的实践。)

缺点是如果您更新枚举列表,则需要记住要更新Highest和/或Lowest的值(如果需要)。如果您忘记了,您将引入错误。

优点是您为循环编写的代码更快且自我说明。


2

如果您将VeryTop = 4添加到枚举中,则必须记得更新Highest

如果您忘记这样做,那么一切都会变得混乱不堪。几个月后,很容易就会忘记这件事。


2
因为这些值可能会随时间变化而改变。假设您将属性设置为(使用您的示例)DrawOrder.Highest 并将其存储在数据库/文档/其他数据源中。
时间流逝。
代码更改。
您的 DrawOrder 枚举已经获得了更多的值,并且您持久化数据中的值现在不再等于 DrawOrder.Highest。它只等于在数据被持久化时 DrawOrder.Highest 映射到的任何值。
您认为这种情况可能会导致问题吗?

我最喜欢这个解释,尽管所有的答案都很相似。谢谢! - Osiris

1

如果您正在持久化枚举并且有可能枚举会更改,那么我会说这只是一个坏主意。如果您没有持久化它,或者没有枚举更改的可能性,那么在大多数情况下,它可能是可以接受的。但是标记的整个意义在于值可能会更改...因此这真的没有任何意义。

然而,当使用这样的结构时,需要小心使用实际想要的枚举。如果您的意思是Top,但却使用了Highest...然后稍后添加了SuperTop并将Highest更改为该值,则您最初的意图现在可能是一个错误。

只有在您想要使用最高或最低值而不考虑其值时,才应使用Marker枚举。

因此,许多人认为这是一种不好的做法,因为在打算使用特定值时很容易使用标记。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接