Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happens under the hood when you cast an enum to an int in C#?

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?

like image 214
Soji Avatar asked Dec 09 '22 07:12

Soji


1 Answers

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.

like image 195
Jon Skeet Avatar answered May 25 '23 18:05

Jon Skeet