发出(在 VB.net 上):使用数组字段(固定大小)制作运行时 class

Emit (on VB.net): making a runtime class with an array field (fixed sized)

我应该在运行时声明我自己的 class。在这个 class 中有一个应该固定大小的数组元素。 我试试这个代码:

Dim an As AssemblyName = New AssemblyName("ClassLibrary1")
Dim assb As AssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndSave)

Dim modb As ModuleBuilder = assb.DefineDynamicModule("ClassLibrary1", "ClassLibrary1.dll", False)
Dim tb As TypeBuilder = modb.DefineType("ClassLibrary1.Class1", TypeAttributes.Class Or TypeAttributes.Public)
Dim constructorArgs As Type() = {GetType(String)}
Dim cb As ConstructorBuilder = tb.DefineDefaultConstructor(MethodAttributes.Public)

Dim fv As FieldBuilder = tb.DefineField("ia", GetType(Boolean).MakeArrayType, FieldAttributes.Public Or FieldAttributes.Static)

t1 = tb.CreateType()

assb.Save("ClassLibrary1.dll")

Dim t = Activator.CreateInstance(t1)

结果是:

如您所见,"ia" 字段有 no_size,如何解决? 感谢帮助

马泰奥·M.

我一直发现弄清楚如何生成代码的最佳方法是让 C#/VB 编译器执行它,然后使用 ILdasm 查看它做了什么。如果您构建 VB class 并查看生成的 IL,您将在静态构造函数中看到这一点(您的数组是静态的,否则请查看实例构造函数):

.method private specialname rtspecialname static 
        void.cctor() cil managed
{
  // Code size       13 (0xd)
  .maxstack  8
  IL_0000: ldc.i4.s   65
  IL_0002:  newarr     [mscorlib]System.Int32
  IL_0007:  stsfld     int32[] VBTest.clsTag:SetPointAlti
IL_000c: ret
} // end of method clsTag:.cctor

如您所见,VB 正在 new-ing 具有所需大小的数组。这就是您需要做的:将代码添加到 class 静态构造函数以创建数组。

Dim cb As ConstructorBuilder = tb.DefineDefaultConstructor(MethodAttributes.Public)
Dim sb As ConstructorBuilder = tb.DefineConstructor(MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes)
Dim fv As FieldBuilder = tb.DefineField("ia", GetType(Boolean).MakeArrayType, FieldAttributes.Public Or FieldAttributes.Static)
Dim ilgen = sb.GetILGenerator()
ilgen.Emit(OpCodes.Ldc_I4_S, 65)
ilgen.Emit(OpCodes.Newarr, GetType(Boolean))
ilgen.Emit(OpCodes.Stsfld, fv)
ilgen.Emit(OpCodes.Ret)

Dim t1 As Type = tb.CreateType()