创建DynamicMethod以调用构造函数
本文关键字:构造函数 调用 DynamicMethod 创建 | 更新日期: 2023-09-27 18:27:10
我试图比较调用编译时未知类型的构造函数的各种方法。我有四个方法在工作:直接调用构造函数(用于定时比较)、调用ConstructorInfo.Invoke、调用Expression.Lambda.Compile和调用Activator.Create。我无法使用的方法是使用DynamicMethod。这是我的代码的一个小样本:
public struct Foo {
private int _val;
public Foo(int val) {
_val = val;
}
public override string ToString() {
return _val.ToString();
}
}
static void Main(string[] args) {
var ctorInfo = typeof(Foo).GetConstructor(new[] { typeof(int) });
var ctorDynamic = new DynamicMethod("CreateFoo",
typeof (Foo), new[] {typeof (int)});
var ilGenerator = ctorDynamic.GetILGenerator();
// Load the int input parameter onto the stack
ilGenerator.Emit(OpCodes.Ldloc_0);
// Call the constructor
ilGenerator.Emit(OpCodes.Call, ctorInfo);
// Return the result of calling the constructor
ilGenerator.Emit(OpCodes.Ret);
// Create a delegate for calling the constructor
var ctorInvoker = (Func<int, Foo>)ctorDynamic.CreateDelegate(
typeof(Func<int, Foo>));
// Call the constructor
var foo = ctorInvoker(5);
}
当我试图在最后一行调用构造函数委托时,我会得到一个VerificationException,上面写着"操作可能会破坏运行时的稳定。"我想我缺少一个或多个操作码,但不知道是哪一个。有人知道使用DynamicMethod进行此操作的正确方法吗?
当尝试编写IL时,最好的选择通常是编写等效的C#代码,然后查看生成的IL。
所以,你写了一个方法,比如:
static Foo f(int i)
{
return new Foo(i);
}
IL将看起来像:
ldarg.0
newobj Foo..ctor
ret
这显示了您犯的两个错误:
- 若要加载方法参数,请使用
ldarg
,ldloc
仅用于局部变量 - 您需要使用
newobj
来调用构造函数,构造函数的行为不像Foo
返回方法
如果您修复了这些错误,您的代码就会正常工作。