当您在C#中将枚举强制转换为int时,会发生什么

本文关键字:int 什么 转换 枚举 | 更新日期: 2023-09-27 18:00:38

我想在C#中实现一个模拟器。

我考虑的一件事是创建一个与字节值相关联的所有操作码的枚举。然而,我想知道这是否不是一个好主意,考虑到我需要多久访问一次该字节值来做一些事情,比如将其用作查找表中的索引,等等。

当您将枚举强制转换为int时,会发生什么?这手术有多贵?简单地通过名称将操作码定义为const字节会更谨慎吗?

当您在C#中将枚举强制转换为int时,会发生什么

它非常便宜——实际上,假设枚举的底层类型为int(这是默认类型),它实际上是一个无操作。例如,这里有一个示例程序:

using System;
enum Foo { A, B, C };
class Test
{
    static void Main()
    {
        Foo x = Foo.B;
        int y = (int) x;
    }    
}

以及为Main生成的代码(未优化):

.method private hidebysig static void  Main() cil managed
{
  .entrypoint
  // Code size       6 (0x6)
  .maxstack  1
  .locals init (valuetype Foo V_0,
           int32 V_1)
  IL_0000:  nop
  IL_0001:  ldc.i4.1
  IL_0002:  stloc.0
  IL_0003:  ldloc.0
  IL_0004:  stloc.1
  IL_0005:  ret
} // end of method Test::Main

实际上,强制转换是为了编译器-内存中的数据已经处于适当的状态,因此它只需要复制值,就像将int复制到int一样。

如果枚举的基础类型不是int,则将枚举强制转换为int与将基础类型强制转换为int具有相同的效果。例如,如果底层类型是long,那么您最终会得到类似conv.i4的内容,就像您通常将long强制转换为int一样。

这在一定程度上取决于枚举本身是否基于int;p

如果是,什么都不发生-枚举完全以int/long的任何形式表示,直到您将它们框起来。MyEnum : int<===>铸造int是一个no-op。在方法重载解析等方面,您所熟悉的大多数区别纯粹是为编译器而存在的;在IL水平上没有任何差异。