当您在C#中将枚举强制转换为int时,会发生什么
本文关键字:int 什么 转换 枚举 | 更新日期: 2023-09-27 18:00:38
我想在C#中实现一个模拟器。
我考虑的一件事是创建一个与字节值相关联的所有操作码的枚举。然而,我想知道这是否不是一个好主意,考虑到我需要多久访问一次该字节值来做一些事情,比如将其用作查找表中的索引,等等。
当您将枚举强制转换为int时,会发生什么?这手术有多贵?简单地通过名称将操作码定义为const字节会更谨慎吗?
它非常便宜——实际上,假设枚举的底层类型为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水平上没有任何差异。