我试图比较调用编译时未知类型的构造函数的各种方法。我有四种方法:直接调用构造函数(用于计时比较),调用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执行此操作的正确方法?
答案 0 :(得分:3)
当尝试编写IL时,最好的选择通常是编写等效的C#代码,然后查看生成的IL。
所以,你写一个像这样的方法:
static Foo f(int i)
{
return new Foo(i);
}
IL看起来像:
ldarg.0
newobj Foo..ctor
ret
这显示了您犯的两个错误:
ldarg
,ldloc
仅用于本地变量。newobj
来调用构造函数,构造函数的行为不像Foo
- 返回方法。如果您修复了这些错误,您的代码就可以正常运行。