枚举应该以0还是1开头?

Aca*_*uza 131 .net c# enums

想象一下,我定义了以下枚举:

public enum Status : byte
{
    Inactive = 1,
    Active = 2,
}
Run Code Online (Sandbox Code Playgroud)

使用枚举的最佳做法是什么?它应该1像上面的例子一样开始,还是以0(没有显式值)开头,如下所示:

public enum Status : byte
{
    Inactive,
    Active
}
Run Code Online (Sandbox Code Playgroud)

And*_*nov 155

框架设计指南:

  • 在您的非标志枚举提供零值.如果没有一个是不恰当的枚举,然后分配零值应作为枚举的默认值的元素.

  • 避免使用标记枚举值为正或负的成员...枚举值为零会产生问题 操作等

  • 提前失败:如果'None'不合适但没有逻辑默认值,我仍然会将零值(并称之为'None'或'Invalid')设置为不应该使用的值,这样就可以了如果该枚举的类成员未正确初始化,则可以很容易地发现未初始化的值,并且在`switch`语句中它将跳转到`default`部分,在那里我抛出`InvalidEnumArgumentException`.否则,程序可能会无意中继续运行枚举的零值,这可能是有效的并且不会被注意到. (27认同)
  • @Allon最好只给出您知道有效的枚举值,然后检查设置器和/或构造函数中的无效值。这样您就可以立即知道某些代码是否无法正常工作,而不是允许具有无效数据的对象存在一段未知的时间并稍后再发现。除非“None”代表有效状态,否则不应使用它。 (2认同)

pst*_*jds 63

好吧,我想我对大多数答案表示不同意,这些答案不是明确地给他们编号.我总是明确地给它们编号,但这是因为在大多数情况下我最终会将它们保存在数据流中,并将它们存储为整数值.如果您没有显式添加值然后添加新值,则可以中断序列化,然后无法准确加载旧的持久化对象.如果您打算对这些值进行任何类型的持久存储,那么我强烈建议您明确设置这些值.

  • +1,同意,但仅限于您的代码由于某些外部原因(例如序列化)而依赖于整数的情况.在其他地方你应该坚持让框架做它的工作.如果你在内部依赖于整数值,那么你可能做错了(参见:让框架做它的工作). (9认同)
  • @Dave:除非你明确说明枚举文本是神圣的,否则如果未来的程序员决定调整名称以使其更清晰或符合某些命名约定,则会使自己失败. (4认同)
  • 我喜欢坚持枚举的文本.使数据库更加可用imo. (3认同)
  • 通常,您不需要显式设置值...即使它们被序列化也是如此.只需要在最后添加新值.这将解决序列化问题.否则您可能需要对数据存储进行版本控制(例如,包含用于在读取/写入值时更改行为的版本的文件头)(或参见memento模式) (2认同)

Fis*_*rdo 14

除非您有特定的理由要更改它,否则请保留枚举的默认值,该值从零开始.

public enum Status : byte
{
    Inactive,
    Active
}
Run Code Online (Sandbox Code Playgroud)


Joe*_*Joe 14

Enum是一种值类型,如果未明确初始化,则其默认值(例如,对于类中的Enum字段)将为0.

因此,您通常希望将0作为已定义的常量(例如,未知).

在您的示例中,如果您想Inactive成为默认值,则它应该具有零值.否则,您可能需要考虑添加常量Unknown.

有些人建议您不要明确指定常量的值.在大多数情况下可能是一个很好的建议,但在某些情况下你会想要这样做:

  • 标志枚举

  • 其值用于与外部系统互操作的枚举(例如COM).


zzz*_*Bov 7

除非你有一个很好的理由使用原始值,你应该永远只能是使用隐式值与引用它们Status.ActiveStatus.Inactive

问题是您可能希望将数据存储在平面文件或数据库中,或者使用其他人创建的平面文件或数据库。如果您自己制作,请使其编号适合 Enum 的用途。

如果数据不是您的,当然您会想要使用原始开发人员用作编号方案的任何内容。

如果您打算将 Enum 用作一组标志,则有一个简单的约定值得遵循:

enum Example
{
  None      = 0,            //  0
  Alpha     = 1 << 0,       //  1
  Beta      = 1 << 1,       //  2
  Gamma     = 1 << 2,       //  4
  Delta     = 1 << 3,       //  8
  Epsilon   = 1 << 4,       // 16
  All       = ~0,           // -1
  AlphaBeta = Alpha | Beta, //  3
}
Run Code Online (Sandbox Code Playgroud)

值应该是 2 的幂,并且可以使用位移操作来表示。None,显然应该是0,但All不太明显-1~0是 和 的二进制否定0结果,其结果是每个位都设置为 的数字1它表示 的值-1。对于复合标志(通常为方便起见),可以使用按位或运算符合并其他值|


Joh*_*0te 5

我要说最好的做法是不对它们进行编号并让它隐含 - 这将从0开始.因为它隐含了语言偏好,这总是很好的遵循:)


Mar*_*iss 5

我会用0开始一个布尔类型的枚举.

除非"Inative"表示"非活动"以外的其他内容:)

这保留了那些标准.


Mic*_*ich 5

我会说,这取决于你如何使用它们.对于标记枚举,将None值设为0是一个好习惯,如下所示:

[Flags]
enum MyEnum
{
    None = 0,
    Option1 = 1,
    Option2 = 2,
    Option3 = 4,
    All = Option1 | Option2 | Option3,
}
Run Code Online (Sandbox Code Playgroud)

当您的枚举可能被映射到数据库查找表时,我将从1开始.对于专业编写的代码而言,这应该没什么关系,但这提高了可读性.

在其他情况下,我会保持原样,不管他们是从0还是1开始.


小智 5

如果未指定编号,则从 0 开始。

显式很重要,因为枚举通常被序列化并存储为 int,而不是字符串。

对于存储在数据库中的任何枚举,我们总是明确编号选项以防止在维护期间转移和重新分配。

根据微软的说法,推荐的约定是使用第一个零选项来表示未初始化或最常见的默认值。

下面是从 1 而不是 0 开始编号的快捷方式。

public enum Status : byte
{
    Inactive = 1,
    Active
}
Run Code Online (Sandbox Code Playgroud)

如果您希望设置标志值以便在枚举值上使用位运算符,请不要从零值开始编号。