我有一个字段定义:
.field public static initonly class A.Program/'<>c' '<>9'
这是C#编译器生成的嵌套类型的一部分。我想使用ILGenerator.Emit构造类似的东西。
使用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#)
答案 0 :(得分:2)
根据ECMA-335:
字段
::= .field
FieldDeclFieldDecl
::=
[‘[’
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‘>’
| 类型‘[’
[绑定 [‘,’
绑定]*
]‘]’
| Typemodopt
‘(’
TypeReference‘)’
| Typemodreq
‘(’
TypeReference‘)’
| 类型pinned
|typedref
|valuetype
TypeReference |unsigned int8
|unsigned int16
|unsigned int32
|unsigned int64
|void
TypeSpec
::=
‘[’
[.module
] DottedName‘]’
| TypeReference | 类型
如您所见,class
不是字段声明的一部分,而是类型本身( TypeSpec 可以在class
或{ {1}}可以省略)。我不确定100%为什么在某些情况下必须使用valuetype
或class
,但也有valuetype
TypeReference ,因此最初可能是类型也可以选择。