Does c# have support for building a constructor using a DynamicMethod
? Consider this class:
public class Foo
{
public string Bar { get; set; }
public Foo(string bar)
{
Bar = bar;
}
}
I would like to create a new constructor for Foo
that takes no arguments, and compile it as a Func<Foo>
. For example:
DynamicMethod dyn = new DynamicMethod("NewInitializer", typeof(Foo), Type.EmptyTypes);
ILGenerator il = dyn.GetILGenerator();
LocalBuilder loc0 = il.DeclareLocal(typeof(Foo));
il.Emit(OpCodes.Ldloca_S, loc0);
il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ret);
Func<Foo> newInitFunc = (Func<Foo>)dyn.CreateDelegate(typeof(Func<Foo>));
Foo f = newInitFunc();
Note, this is just one of the implementations I have tried. Everything ends up throwing an AccessViolationException
:
Operation Could Destabilize the Runtime
when I call the method. Is it even possible to create a constructor using a DynamicMethod
?
If inheriting from those types is possible, you could create a class using Emit that inherits from the the existing type and doesn't call the base constructor.
var typeToLoad = typeof(Foo);
var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Dynamic"), AssemblyBuilderAccess.Run);
var moduleBuilder = assemblyBuilder.DefineDynamicModule("Dynamic");
var typeBuilder = moduleBuilder.DefineType(typeToLoad.Name, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AnsiClass | TypeAttributes.AutoClass, typeToLoad);
// create a constructor that doesn't call the base constructor
var constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName, CallingConventions.Standard, Type.EmptyTypes);
var ilGenerator = constructorBuilder.GetILGenerator();
ilGenerator.Emit(OpCodes.Ret);
// create a factory method so we could create a delegate for it
var methodBuilder = typeBuilder.DefineMethod("Create", MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig, typeBuilder, Type.EmptyTypes);
ilGenerator = methodBuilder.GetILGenerator();
ilGenerator.Emit(OpCodes.Newobj, constructorBuilder);
ilGenerator.Emit(OpCodes.Ret);
var generatedType = typeBuilder.CreateType();
var factory = (Func<Foo>)generatedType.GetMethod("Create", BindingFlags.Public | BindingFlags.Static).CreateDelegate(typeof(Func<Foo>));
This runs as fast as the new
operator.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.