【问题标题】:What is the point of using ints as enums使用整数作为枚举有什么意义
【发布时间】:2025-12-18 06:20:08
【问题描述】:

为什么很多人都这样做枚举:

public enum EmployeeRole
{
  None = 0,
  Manager = 1,
  Admin = 2,
  Operator = 3
}

而不仅仅是做:

public enum EmployeeRole
{
  None,
  Manager,
  Admin,
  Operator
}

有优势吗?

【问题讨论】:

    标签: c# enums coding-style


    【解决方案1】:

    有优势吗?

    可维护性。假设这些整数值最终保存在数据库中。您不希望将来向枚举添加新值并更改值,因为您插入的值会改变未指定的值。

    清晰。明确是一件好事。再说一次,我们正在从某个遗留应用程序的数据库中读取整数。所以代码已经有了特定的含义,我们要明确地与它们对齐。我们可以说

    public enum EmployeeRole {
        None,
        Manager,
        Admin,
        Operator
    }
    

    也许这与旧规范完全一致,或者我们可以说

    public enum EmployeeRole {
        None = 0,
        Manager = 1,
        Admin = 2,
        Operator = 3
    }
    

    现在更容易理解我们是否符合旧规范。

    【讨论】:

    • 我假设不存储枚举的字符串值而是存储关联的整数是常态?我通常只是存储字符串值。这只是一种不好的做法,因为它浪费字节吗?
    • 这显然是问题的正确答案,但我想补充一点,我真的不认为将枚举值存储在数据库中是一个好主意。见:wtfperminute.blogspot.com/2011/02/…
    • 我假设不存储枚举的字符串值而是存储关联的整数是常态?我通常只是存储字符串值。这只是不好的做法,因为它浪费字节吗? ——
    【解决方案2】:

    当您在其他地方有合同时,它很有用。如果您将枚举存储在数据库中,您希望显式键入数字,以确保不会通过在中间插入新项目而意外地重新编号枚举。

    【讨论】:

      【解决方案3】:

      它明确定义一个值,而不是让编译器在编译时处理它。在您提供的情况下,除了可读性和定义明确之外,它真的没有任何意义。它不会伤害任何东西,并且会导致与未明确设置它们相同的 MISL。但是,如果您的枚举涉及到特定值,而不是像上述情况那样自动递增,这种显式定义会非常方便。

      public enum MyEnum
      {
      
          First = 1,
          Second = 2,
          Eleventh = 11
      
      }
      

      【讨论】:

        【解决方案4】:

        例如,当您在数据库中存储值时,建议在数字和符号值之间进行固定映射。如果你没有明确指定数值,编译器会按顺序编号,所以如果你插入一个新的,就会出现不匹配的情况。

        【讨论】:

          【解决方案5】:

          我看到了两个主要优势:

          • 提供与其他事物相关的值(如数据库值、间隔等)。请注意,您不需要提供有序值。例如,它可以是 1、23、2 和 4。
          • 当您需要数值时,它更具可读性。

          【讨论】:

            【解决方案6】:

            这有助于避免仅仅因为有人重新排列类而改变这些所谓的常量值。假设您有一个新员工决定“无”应该放在列表的最后:

            public enum EmployeeRole
            {
              Manager,
              Admin,
              Operator,
              None
            }
            

            好吧,如果您只是直接从 EmployeeRole.Whatever 访问这些值,那也没什么大不了的。但是我见过的大多数枚举在保存在数据库中时都会在某些时候转换为整数值。这意味着您存储中的所有“None”元素都刚刚转换为“Manager”。

            如果有人只是在 Admin 和 Operator 之间插入一个新的 EmployeeRole,也会出现同样的问题。

            当您认为枚举没有适当的“默认”值时,会出现另一个优势。例如,如果有人忘记在 ORM 中映射 EmployeeRole 字段,则从存储库中提取的对象将始终显示为具有None 角色(0 始终是枚举的默认值)。根据您的软件处理None 的方式,这种错误可能会在一段时间内未被发现。但如果你这样做:

            public enum EmployeeRole
            {
              Manager = 1,
              Admin = 2,
              Operator = 3
            }
            

            ...然后将其与快速失败技术结合使用,您可以快速捕获提供了无效“0”值的错误:

            public RightsManager GetByEmployeeRole(EmployeeRole role)
            {
                Require.That(role.IsDefined()); // throws an exception if role is not defined.
                // find the rights manager for this role.
            }
            

            【讨论】:

            • 此外,“None”应该几乎总是为零,以便枚举类型的字段被初始化为合理的默认值。
            • @Eric Lippert:是的,假设你有一个合理的默认值。 (见我的编辑)