c#是否支持使用DynamicMethod
构建构造函数?考虑这个课程:
public class Foo
{
public string Bar { get; set; }
public Foo(string bar)
{
Bar = bar;
}
}
我想为Foo
创建一个不带参数的新构造函数,并将其编译为Func<Foo>
。例如:
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();
注意,这只是我尝试过的一个实现。一切都最终抛出AccessViolationException
:
操作可能会使运行时不稳定
当我调用方法时。甚至可以使用DynamicMethod
?
答案 0 :(得分:0)
如果可以从这些类型继承,则可以使用Emit创建一个继承自现有类型的类,而不调用基本构造函数。
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>));
此速度与new
运算符一样快。