发出(在 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()
我应该在运行时声明我自己的 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()