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

发布于 2024-11-17 15:45:36 字数 185 浏览 1 评论 0原文

我正在寻找用 C# 实现模拟器。

我考虑的事情之一是创建与其字节值关联的所有操作码的枚举。但是,我想知道考虑到我需要多久访问该字节值才能执行诸如将其用作查找表中的索引等操作,这是否不是一个好主意。

当您将枚举转换为一个 int,会发生什么?这样的手术费用有多高?简单地将我的操作码按其名称定义为 const 字节会更谨慎吗?

I'm looking to implement an emulator in C#.

One of the things I considered was creating an enum of all the opcodes associated with their byte value. However, I wonder if this might not be a good idea considering how often I'm going to need to access that byte value to do things like use it as the index in a lookup table, etc, etc.

When you cast an enum to an int, what happens? How expensive of an operation is this? Would it be more prudent to simply define my opcodes as const bytes by their name?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

习ぎ惯性依靠 2024-11-24 15:45:36

它非常便宜 - 实际上,它实际上是一个无操作,假设枚举有一个底层类型 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 具有相同的效果int。例如,如果基础类型为 long,您最终会得到类似于 conv.i4 的内容,其方式与转换 long 的方式相同> 通常为 int

It's very cheap - it's effectively a no-op, really, assuming the enum has an underlying type of int to start with (which is the default). For example, here's a sample program:

using System;

enum Foo { A, B, C };

class Test
{
    static void Main()
    {
        Foo x = Foo.B;
        int y = (int) x;
    }    
}

And the generated code for Main (not optimized):

.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

Effectively the cast is for the sake of the compiler - the data in memory is already in an appropriate state, so it just needs to copy the value just like it would copying an int to an int.

If the underlying type of the enum isn't an int, then casting the enum to int has the same effect as casting the underlying type to int. For example, if the underlying type is long, you'll end up with something like conv.i4 in the same way that you would casting long to int normally.

指尖凝香 2024-11-24 15:45:36

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

如果是,什么也不会发生 - 枚举完全用其 int 表示/ long 任何形式,直到您将它们装箱为止。从 MyEnum : int 进行转换 <===> int 是一个无操作。您所熟悉的在方法重载解析等方面的大多数区别纯粹是针对编译器而存在的;在 IL 级别上没有任何区别。

It depends a bit on whether the enum is itself based on int ;p

If it is, nothing happens - enums are represented entirely in their int / long whatever form until you box them. Casting from MyEnum : int <===> int is a no-op. Most distinctions that you are familiar with in terms of method overload resolution etc exist purely for the compiler; at the IL level there is no difference whatsoever.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文