Enum w IL

Zastanawialiście się jak wygląda enum po skompilowaniu? Ja niedawno doznałem fascynacji ILem i zacząłem przyglądać się jak różne rzeczy są implementowane.

Wyszedłem od bardzo prostego kodu w C#

namespace EnumTest
{
    public enum E
    {
        A,
        B,
        C,
        D
    }
}

Następnie uruchomiłem csc.exe i skompilowałem powyższy kod do enumtest.dll. Za pomocą narzędzi takich jak DotPeek czy ILSpy, byłem w stanie podejrzeć części ILa, ale chciałem zobaczyć całość, więc sięgnąłem po ildasm.exe. Jest to graficzne narzędzie, które w przeciwieństwie do większości narzędzi dotnetowych leży nie w %windows%\Microsoft.NET\Framework\ver, a w C:\Program Files (x86)\Microsoft SDKs\Windows\ver\bin\NETFX ver tools.

Poleceniem File > Dump byłem w stanie uzyskać plik .il, który zawiera kod mojej biblioteki. Nie będę teraz wchodził w szczegóły ILa, będzie na to inny post. Chcę natomiast się przyjrzeć jaki kod IL odpowiada powyższemu w C#.

.class public auto ansi sealed EnumTest.E
       extends [mscorlib]System.Enum
{
  .field public specialname rtspecialname int32 value__
  .field public static literal valuetype EnumTest.E A = int32(0x00000000)
  .field public static literal valuetype EnumTest.E B = int32(0x00000001)
  .field public static literal valuetype EnumTest.E C = int32(0x00000002)
  .field public static literal valuetype EnumTest.E D = int32(0x00000003)
}

Więc po pierwsze widzimy, że enum tworzy nam klasę, po której nie można dziedziczyć (sealed). Ta klasa dziedziczy po System.Enum z mscorlib.dll. Następnie mamy kilka pól.

.field public specialname rtspecialname int32 value__ informuje nas o tym jaki typ znajduje się pod tym enumem i widzimy że jest to int32.

Następnie mamy kilka statycznych publicznych pól typu EnumTest.E o nazwie odpowiednio A,B,C,D i kolejnych wartościach int32

Jeszcze nie wiem co znaczą wszystkie widoczne tu atrybuty (np. literal, czy rtspecialname). Zacząłem czytać standard ECMA 335, który opisuje IL, ale ma on niemal 600 stron, więc trochę mi to zajmie ☺