我希望用C#实现一个模拟器。
我考虑的一件事是创建一个与其字节值相关的所有操作码的枚举。但是,我想知道这可能不是一个好主意,考虑到我需要访问该字节值以执行诸如将其用作查找表中的索引等等的事情。
当你将枚举转换为int时,会发生什么?手术有多贵?简单地将我的操作码按名称定义为const字节会更为谨慎吗?
答案 0 :(得分:9)
它非常便宜 - 它实际上是一个无操作,实际上,假设枚举有一个基础类型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
有效地,强制转换是为了编译器 - 内存中的数据已经处于适当的状态,因此它只需复制值就像复制{{1}一样到int
。
如果枚举的基础类型不是 int
,则将枚举强制转换为int
与将基础类型转换为{{1}具有相同的效果}}。例如,如果基础类型为int
,则最终会使用int
之类的内容,就像通常将long
投射到conv.i4
一样。
答案 1 :(得分:5)
这取决于枚举本身是基于int
; p
如果是,没有任何反应 - 枚举完全以int
/ long
形式表示,直到您将它们装箱。来自MyEnum : int
< ===>的投射int
是无操作。您在方法重载解析等方面熟悉的大多数区别纯粹存在于编译器中;在IL级别上没有任何区别。