CIL:将“ class”关键字分配给“ .field”是什么意思?

时间:2018-11-26 10:47:45

标签: c# .net cil

我有一个字段定义:

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

这是C#编译器生成的嵌套类型的一部分。我想使用ILGenerator.Emit构造类似的东西。

  • 我试图在ILSpy中查看C#,但是它隐藏了嵌套 为我输入类型(“嵌套类型”)。
  • 我在ECMA-335中什么都没找到。

使用ILDasm / ILasm,我构建了以下代码,希望它将给我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 ***********************

使用

ilasm /dll /debug test.il

ILSpy将我的.field public static initonly class System.Object 'x'行转换为.field public static initonly object x(省略了class关键字并生成了public static readonly object x; C#)

1 个答案:

答案 0 :(得分:2)

根据ECMA-335:

  

字段 ::= .field FieldDecl

     

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

     

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

     

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

如您所见,class不是字段声明的一部分,而是类型本身( TypeSpec 可以在class或{ {1}}可以省略)。我不确定100%为什么在某些情况下必须使用valuetypeclass,但也有valuetype TypeReference ,因此最初可能是类型也可以选择。