Что происходит под капотом, когда вы приводите enum к int в C#?

Я хочу реализовать эмулятор на С#.

Одна из вещей, которые я рассматривал, заключалась в создании перечисления всех кодов операций, связанных с их значением байта. Однако мне интересно, может ли это быть плохой идеей, учитывая, как часто мне нужно будет обращаться к этому байтовому значению, чтобы делать такие вещи, как использование его в качестве индекса в таблице поиска и т. д. и т. д.

Что происходит, когда вы приводите enum к int? Насколько это дорогая операция? Было бы разумнее просто определить мои коды операций как константные байты по их имени?


person Soji    schedule 27.06.2011    source источник
comment
Зависит от. Является ли базовый тип перечисления уже int? Если это так, то это по существу не-операция. Значение уже сохранено как int.   -  person Cody Gray    schedule 27.06.2011


Ответы (2)


Это очень дешево - на самом деле это не работает, если предположить, что перечисление имеет базовый тип 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.

person Jon Skeet    schedule 27.06.2011

Это немного зависит от того, основано ли само перечисление на int ;p

Если это так, ничего не происходит — перечисления представлены полностью в их int / long любой форме, пока вы не упакуете их. Кастинг из MyEnum : int ‹===> int невозможен. Большинство различий, с которыми вы знакомы в терминах разрешения перегрузок методов и т. д., существуют исключительно для компилятора; на уровне ИЛ разницы никакой нет.

person Marc Gravell    schedule 27.06.2011