【问题标题】:Scenarios when it is worthful to cast enum to its value值得将枚举转换为它的值的场景
【发布时间】:2026-02-09 21:50:01
【问题描述】:

我的一个 Windows 应用程序中有枚举,如下所示:

private enum ModificationType
{
    Insert = 0,
    Update = 1,
    Delete = 2
}

我有以下功能:

private void UpdateDatabaseTransactions(ModificationType _modifcationType)
        {
int modType = (int)_modifcationType;
if (modType == 0) {...}
if (modType == 1) {...}
if (modType == 2) {...}

我也可以像下面这样使用它:

if (_modifcationType == ModificationType.Insert) {...}
if (_modifcationType == ModificationType.Update) {...}
if (_modifcationType == ModificationType.Delete) {...}
}

两者之间有什么区别,在哪些情况下我必须对值进行类型转换和使用,使用上述任何一种是否有任何性能提升,或者两者相同?

【问题讨论】:

  • 我相信enums 的最佳实践是为未初始化的enums 设置错误状态为0

标签: c# casting enums


【解决方案1】:

当您决定稍后更改 ModificationType 枚举时会发生什么?例如:

private enum ModificationType
{
    Insert = 0,

    /* Oops, need a special insert type here */
    InsertSpecial = 1,

    Update = 2,
    Delete = 3
}

诚然,这是一个人为的例子。 (但当然不是不可能 - 假设您的 enum 用于引用一些引入重大更改的外部依赖项,例如 C API。)

但是,如果您按值引用这些枚举类型,则必须跟踪它们的所有引用。你想通过你的代码来尝试找出数字 3 是用来引用那个枚举还是其他一些随机常量?

相反,您应该使用ModificationType.Delete,这样您就不必担心这些问题。毕竟,这就是 enum 类型存在的原因。

使用 ModificationType.Delete 代替 4、5、6 或任何可能的值不会降低性能。

【讨论】:

    【解决方案2】:

    如果您从代码外部读取 _modifcationType,我只能想象您需要转换的场景 - 即:从文件、数据库、JSON 等。

    除此之外 - 我会在不强制转换的情况下使用它 - 特别是在 switch..case 块中。

    【讨论】:

    • 我在 SO 上遇到了一个答案,作者是 @johnny g,他说不要在没有在 switch 中转换大小写的情况下使用,你可以在这里参考他的答案:*.com/questions/1758321/…,他说“不知道为什么,但我最近发现这个“功能”非常有用。前几天我写了这样的东西“
    【解决方案3】:

    在将枚举实例与特定值进行比较时,您应该始终使用命名的枚举值。使用ModificationType.Insert0 更安全。值的编辑不会影响使用 ModificationType.Insert 的现有比较,但会默默地导致依赖它的函数的行为为 0。

    【讨论】:

      【解决方案4】:

      它们几乎是等价的(假设您使用的整数值实际上与您在枚举中使用的值匹配)。您不会注意到两者之间的性能差异。

      话虽如此,您应该尽可能使用实际的 Enum 值。使用枚举的全部意义在于为整数赋予有意义的值。如果对代码库不熟悉的人查看第一个示例,他们将不知道代码在做什么。如果他们看第二个,它实际上仍然是有意义的。

      【讨论】:

        【解决方案5】:

        两个示例应该运行相同。不过,由于可读性,我建议使用第二个。它比第一个更容易理解和维护。

        【讨论】:

          【解决方案6】:

          下半场:如果你对值进行数学运算,你可能需要从枚举中进行强制转换,也很少见,因为枚举会自动转换为相应的整数类型。

          【讨论】:

            【解决方案7】:

            使用枚举值。一个命名的枚举值,比如你的 ModificationType.Delete 是一个编译时常量。

            除非您需要这样做:

            • 枚举 (0) 的默认值未定义,或者定义为 Unknown 或类似的东西:

              public enum ModificationType
              {
               [ Unknown = 0 , ]
               Insert = 1 ,
               Update = 2 ,
               Delete = 3 ,
              }
              
            • 当您对它们执行一些操作(例如 if/then 语句)时,请使用开关并针对超出范围的值抛出 InvalidOperationException 或类似异常。当枚举的域扩展时,这将保存您的培根(或其他人的培根),或者您遇到枚举实例未正确初始化为正确值的错误:

              switch ( someModificationType )
              {
              case ModificationType.Insert : performInsert() ; break ;
              case ModificationType.Delete : performDelete() ; break ;
              case ModificationType.Update : performUpdate() ; break ;
              default :
                throw new InvalidOperationException() ;
                break ;
              }
              

            我最喜欢的 MS Word 错误之一是在 Word 中执行某些操作,然后遇到一个带有 OK 按钮的弹出消息框和神秘消息:“此消息永远不应该出现”。不完全有用,但开发者的心在正确的地方。

            【讨论】: