CIL: What does the "class" keyword mean when assigned to a ".field"?

1

I have a field definition:

.field public static initonly class A.Program/'<>c' '<>9'

This is part of a nested type generated by the C# compiler. I would like to construct something similar using ILGenerator.Emit.

  • I have attempted to view the C# in ILSpy, but it hides the nested type ("Nested Types") for me.
  • I haven't found anything in ECMA-335.

Using ILDasm/ILasm, I built the following code in the hope it would give me the C#:

// Metadata version: v4.0.30319
.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..
  .ver 4:0:0:0
}
.assembly Test
{

  // --- The following custom attribute is added automatically, do not uncomment -------
  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 03 01 00 00 00 00 ) 

  .hash algorithm 0x00008004
  .ver 0:0:0:0
}
.module Test
// MVID: {9110E73E-F37F-4E22-9D43-20F26D4A4C8F}

// --- The following custom attribute is added automatically, do not uncomment -------
//  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 03 01 00 00 00 00 ) 

.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003       // WINDOWS_CUI
.corflags 0x00000001    //  ILONLY
// Image base: 0x0000029D41150000


// =============== CLASS MEMBERS DECLARATION ===================

.class private auto ansi Test
       extends [mscorlib]System.Object
{
  .field public static initonly class System.Object 'x'

} // end of class Test


// =============================================================

// *********** DISASSEMBLY COMPLETE ***********************

with

ilasm /dll /debug test.il

ILSpy translates my .field public static initonly class System.Object 'x' line to .field public static initonly object x (omitting the class keyword and resulting in public static readonly object x; C#)

c#
.net
cil
asked on Stack Overflow Nov 26, 2018 by Matt Jacobsen • edited Nov 26, 2018 by Matt Jacobsen

1 Answer

2

Per ECMA-335:

Field ::= .field FieldDecl

FieldDecl ::= [ ‘[’ Int32 ‘]’ ] FieldAttr* Type Id [ ‘=’FieldInit | at DataLabel ]

FieldAttr ::= assembly | famandassem | family | famorassem | initonly | literal | marshal ‘(’ NativeType ‘)’ | notserialized | private | compilercontrolled | public | rtspecialname | specialname | static
Type ::= ‘!’ Int32 | ‘!!’ Int32 | bool | char | class TypeReference | float32 | float64 | int8 | int16 | int32 | int64 | method CallConv Type ‘*’ ‘(’ Parameters ‘)’ | native int | native unsigned int | object | string | Type ‘&’ | Type ‘*’ | Type ‘<’ GenArgs ‘>’ | Type ‘[’ [ Bound [ ‘,’ Bound ] * ] ‘]’ | Type modopt ‘(’ TypeReference ‘)’ | Type modreq ‘(’ TypeReference ‘)’ | Type pinned | typedref | valuetype TypeReference | unsigned int8 | unsigned int16 | unsigned int32 | unsigned int64 | void

TypeSpec ::= ‘[’ [ .module ] DottedName ‘]’ | TypeReference | Type

As you can see, class is not a part of the field declaration, but of the type itself (TypeSpec can be used in other places where class or valuetype can be omitted). I am not 100 % sure why class or valuetype must be used in some cases, but there is also boxed TypeReference, so possibly originally, a form of the type could have been chosen as well.

answered on Stack Overflow Nov 27, 2018 by IS4

User contributions licensed under CC BY-SA 3.0