【问题标题】:How to compare enum and int values?如何比较 enum 和 int 值?
【发布时间】:2011-07-13 15:55:18
【问题描述】:
enum MyEnum
{
    Invalid=0,
    Value1=1,
    Value1=2,
}

void main ()
{
    MyEnum e1 = MyEnum.Value1;
    int i1 = 2;

    // Is there any difference how to compare enumEration values with integers?
    if ( e1==(MyEnum)i1 )... // 1st

    if ( (int)e1==i1 )... // 2nd

在上述每种情况下,我们都将 enum 转换为 int 或将 int 转换为 enum。

这些转化(性能,任何其他)有什么不同吗?还是完全一样?

谢谢。

附:在当前示例中,我将其与“幻数”进行比较,但在实际应用中,我从 DB 的整数字段中获取数据。

【问题讨论】:

  • 引入枚举类型部分是为了避免幻数。为什么要将其转换回整数?
  • Cast Int To Enum 可能会有所帮助。
  • 选择第二个选项。如果整数超出枚举中定义的范围,第一个可能会导致异常。
  • 在当前示例中,我与“幻数”进行比较,但在实际应用中,我从 DB 的整数字段中获取数据。
  • @XichenLi,有一种情况是使用整数值。这是您想要检查 Enum 参数的排名,查看某个值是否更高/更低等时。

标签: c# .net enums


【解决方案1】:

这会有所帮助。

var constant = 1;
if(constant == (int)MyEnum.Valid1){
......
}

【讨论】:

    【解决方案2】:

    它们完全一样。使用 Debug, Windows, Disassembly (Ctrl-Alt-D) 显示生成的 IL 可以:

    MyEnum e1 = MyEnum.Value1;
    00260834  mov         dword ptr [ebp-3Ch],1  
    int i1 = 2;
    0026083B  mov         dword ptr [ebp-40h],2  
    
    // Is there any difference how to compare enumEration values with integers?
    if (e1 == (MyEnum) i1) 
    00260842  mov         eax,dword ptr [ebp-3Ch]  
    00260845  cmp         eax,dword ptr [ebp-40h]  
    00260848  sete        al  
    0026084B  movzx       eax,al  
    0026084E  mov         dword ptr [ebp-44h],eax  
    00260851  cmp         dword ptr [ebp-44h],0  
    00260855  je          00260858  
    ; // 1st
    00260857  nop  
    
    if ((int)e1 == i1)
    00260858  mov         eax,dword ptr [ebp-3Ch]  
    0026085B  cmp         eax,dword ptr [ebp-40h]  
    0026085E  sete        al  
    00260861  movzx       eax,al  
    00260864  mov         dword ptr [ebp-48h],eax  
    00260867  cmp         dword ptr [ebp-48h],0  
    0026086B  je          0026086E  
    ; // 2nd
    0026086D  nop  
    

    【讨论】:

      【解决方案3】:

      当您从数据库中读取 int 时,我建议您将其转换为具有代表性的枚举值。这将大大提高代码的可读性。

      enum MyEnum
      {
          Invalid=0,
          Value1=1,
          Value1=2,
      }
      
      MyEnum dbValue = ReadEnumFromDB();
      if(dbValue == MyEnum.Invalid)
      {
         ...
      }
      

      【讨论】:

      • dbValue==MyEnum.Invalid 的可读性与 intDbValue==(int)MyEnum.Invalid 相同
      • 如果该数据库列始终由 MyEnum 值正确表示,则在调试时更容易准确识别 int 应该表示的内容。
      【解决方案4】:

      .Net 中的枚举实际上只是基本整数类型的漂亮元结构。 (默认情况下,该类型是 int。)如果您查看 Generated IL 的枚举,您会发现它实际上是一个标准类型,每个特定枚举元素都有几个静态字段。因此,枚举可以透明地在整数类型之间进行转换。

      Related answer

      【讨论】:

      • Metthes,您的消息似乎是对 Mellvar 答案的“评论”,而不是答案本身。
      • 我想我可以添加其他人开始使用的“没关系”。但这并没有改变我的其余部分。
      • 和链接的问题与这个问题没有太大关系。
      【解决方案5】:

      我会选择第二种方法。对我来说,这更符合逻辑。 如果i2 超出范围,它将消除运行时异常。

      【讨论】:

      • 不会出现运行时异常。任何int(或匹配的整数类型,如果枚举基数发生更改)都可以转换为该枚举。
      • 这个答案意味着如果 i1 是 10 就会出现异常。不会有。
      • @Daniel:它将是一个 MyEnum 类型的值,其基础值为 10。接下来会发生什么取决于你用它做什么。例如,如果您调用 ToString,它将只返回“10”。但也不例外。
      • 我希望这是一个运行时异常。
      • @Daniel:当然,我希望至少支持一组受限值,可能以及现有的“ C# 实际采用的命名数字”方法。
      【解决方案6】:

      无论您使用哪个,它们的性能都相同。如果整数值没有枚举,.net 会在运行时创建一个。不能有任何例外。

      不过,Xichen Li 是对的 - 为什么要将枚举与整数值进行比较?

      【讨论】:

      • .NET 不需要“创建”不存在的值。基本上一个枚举值知道它是什么类型,但只包含相关整数的位。为什么需要创建任何东西?
      • 可能我表达不正确;我的意思是,像 ((MyEnum)5).ToString() 这样的东西会产生看起来像枚举的“新”成员的东西(假设 MyEnum 没有值 == 5)。
      • 嗯,它会返回“5”...但我仍然不会称该过程为“创建”新值。这就是 ToString 的行为方式,仅此而已。转换本身涉及的代码no考虑值是否在枚举中定义。
      • 我有一个用例。框架中定义的 HttpStatusCode 枚举。我想检查所有高于 400 的值,以便以特定方式处理它们。
      • @Melllvar Mono 项目,检查当前操作系统。 msdn.microsoft.com/de-de/library/3a8hyw88(v=vs.110).aspx 为例
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-24
      • 1970-01-01
      • 1970-01-01
      • 2015-07-05
      相关资源
      最近更新 更多