在中间添加枚举

6
我发现一个代码,我的同事最近修改了一个现有的枚举并在最后一个枚举之前添加了另一个枚举,我猜他可能是因为最后一个枚举是None(我们不在同一时区讨论)。
我的担忧是如果任何解决方案中的代码尝试获取None Enum的整数值(幸运的是我没有找到任何地方),那么这可能会产生错误结果。
要么将Enum添加到最后,要么将每个Enum与整数值相关联以解决排序问题,这样安全吗?
请给予一些指导。
更新: 在SO问题中,我看到@Marc Gravell提到在中间插入是危险的,我是否理解他的正确?请参见https://dev59.com/6Wcs5IYBdhLWcg3wmlIK#12716043

如果您从未在整个代码库中使用过某个枚举项,那么如果将其下移一个位置(如果它是最后一项),您如何通过此操作破坏代码? - T.S.
1
@T.S.编译器会自动生成一个支持值 - 如果您将其转换,那么如果您在现有值之间添加新值,则该值将不同。 - Daniel A. White
是的,你提出的两个选项在某些情况下更安全,特别是当你的代码期望某些枚举值与特定整数值相关联时,但这也是一种不好的实践。总的来说,你同事的更改应该没问题。 - Rufus L
@DanielA.White 我理解。但是如果他说它没有被使用,那么它就不可能出现问题。有很多变量。这段代码是否作为第三方代码使用?等等。 - T.S.
“None” 应该始终是第一个项目,因为该类型的自动填充空变量(例如类变量或数组元素)将被初始化为第一个值(具有整数值 0 的值)。也就是说,除非枚举中定义了特定的数字,否则它永远不应该被用作或与整数进行比较。 - Nyerguds
2个回答

5

enum列表中任何位置添加新值都没有问题,因为当包含新enum的代码重新编译时,编译器会为所有值计算正确的序数。

如果旧enum的实例已经被持久化,比如存储在数据库中,那么就会产生问题。在这种情况下,显式分配值是更好的选择,因为存储的值不会受到重新编译的影响,并且在检索时将转换为不正确的值。


我的项目中有一些枚举有一个相当长的列表,比如20个成员之类的,给它们分配一个值是不是太多了点? - Vivek Shukla
2
@Vivek_Shukla 除非你做类似 if (someEnum == 1) 这样的事情,或者它被存储在数据库中。如果没有分配数字,那么你就不会有问题。 - Steve
@Vivek_Shukla Marc提出的两点适用于任何enum修改,无论是在中间还是在结尾。他的第二点关于序列化的问题与我关于持久化enum值的说法完全相同。 - Sergey Kalinichenko
@dasblinkenlight 他的评论让我想到,如果有些代码正在使用整数值,例如 public enum Status { Good, Fair, Poor } (UInt16)Status.Good,那么这可能会非常危险。请在数据库部分提供一些解释。 - Vivek Shukla
1
如果您将枚举值存储在数据库中,然后枚举以一种使得这些值现在与不同的枚举名称相关联的方式发生更改,那么情况就会变得危险。如果您发现 Something.Status == Poor 并将其保存到数据库中作为 Something.Status = 2,然后稍后在您的 enum 定义中在 Poor 之前插入一个新值,那么当从数据库中检索并在某个 UI 中呈现历史记录时,它将显示为 Something.Status = NewInsertedStatus - Rufus L

2
如果您担心会出现破坏性变化,可以采取您建议的任何一种方法。最安全的方法是为每个成员分配一个值,这样就很明确了,而且您不必依赖于编译器为您生成任何内容。

我的项目中有一些枚举类型的列表非常长,例如20个成员,给它们分配一个值是否有点过度了? - Vivek Shukla
@Vivek_Shukla 如果你第一次做的话就不会。 - Daniel A. White
3
如果你担心输入过多,那么从技术角度上说,你只需要为最后一个项目和要插入的项目分配值。例如:public enum Status { Good, Fair, Poor, InsertedItem = 4, Bad = 3}。请注意,这不会改变原来的意思。 - Rufus L
@RufusL 我喜欢你的建议。 - Vivek Shukla
3
如果在“Bad”后面添加一个项目而没有给它赋值,那么它也会自动被赋值为“4”。请勿这样做。 - Rufus L

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