'How do I use TypeBuilder to create derived type with static field of base type?
I am having an issue using TypeBuilder to dynamically create a derived type that has a static field of the base type, that is initialized to a new instance of the created type.
Essentially, I want to create this dynamically:
public abstract class Base {
...
}
public class Imp : Base
{
public static readonly Base B;
static Imp(){
B = new Imp();
}
...
}
Using SharpLab, I see the following IL for the derived class:
.class public auto ansi Imp
extends Base
{
// Fields
.field public static initonly class Base B
// Methods
.method private hidebysig specialname rtspecialname static
void .cctor () cil managed
{
// Method begins at RVA 0x2059
// Code size 12 (0xc)
.maxstack 8
IL_0000: nop
IL_0001: newobj instance void Imp::.ctor()
IL_0006: stsfld class Base Imp::B
IL_000b: ret
} // end of method Imp::.cctor
.method public hidebysig specialname rtspecialname
instance void .ctor () cil managed
{
// Method begins at RVA 0x2066
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void Base::.ctor()
IL_0006: nop
IL_0007: ret
} // end of method Imp::.ctor
} // end of class Imp
I have the following for my TypeBuilder, in an attempt to recreate the IL shown:
private static Type CreateImp()
{
var assyBldr = AssemblyBuilder.DefineDynamicAssembly(
new AssemblyName("TestAssy"), AssemblyBuilderAccess.RunAndCollect);
var moduleBldr = assyBldr.DefineDynamicModule("TestMod");
var typeBldr = moduleBldr.DefineType("Imp",
TypeAttributes.Public |
TypeAttributes.Sealed |
TypeAttributes.Class |
TypeAttributes.AnsiClass |
TypeAttributes.AutoLayout |
TypeAttributes.BeforeFieldInit |
TypeAttributes.AutoClass,
typeof(Base));
// Add the static instance field
var fieldBldr = typeBldr.DefineField("B",
typeof(Base),
FieldAttributes.Public |
FieldAttributes.Static |
FieldAttributes.InitOnly);
var ctorBldr = typeBldr.DefineConstructor(
MethodAttributes.Private |
MethodAttributes.Static,
CallingConventions.Standard,
Type.EmptyTypes);
var ctorILGen = ctorBldr.GetILGenerator();
var objCtor = typeBldr.DefineDefaultConstructor(MethodAttributes.Public);
ctorILGen.Emit(OpCodes.Newobj, objCtor);
ctorILGen.Emit(OpCodes.Stfld, fieldBldr);
ctorILGen.Emit(OpCodes.Ret);
var type = typeBldr.CreateType();
return type;
}
but when I use it, I get an InvalidProgramException
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
