C# 为什么这种动态方法(ldarg.1、newobj、ret)会触发VerificationException?
我有一个方法,它将构造函数包装在动态工厂方法中:C# 为什么这种动态方法(ldarg.1、newobj、ret)会触发VerificationException?,c#,reflection,reflection.emit,dynamicmethod,verificationexception,C#,Reflection,Reflection.emit,Dynamicmethod,Verificationexception,我有一个方法,它将构造函数包装在动态工厂方法中: static Func<TArg1, TResult> ToFactoryMethod<TArg1, TResult>(this ConstructorInfo ctor) where TResult : class { var factoryMethod = new DynamicMethod( name: string.Format("_{0:N}", Guid.N
static Func<TArg1, TResult> ToFactoryMethod<TArg1, TResult>(this ConstructorInfo ctor)
where TResult : class
{
var factoryMethod = new DynamicMethod(
name: string.Format("_{0:N}", Guid.NewGuid()),
returnType: typeof(TResult),
parameterTypes: new Type[] { typeof(TArg1) });
ILGenerator il = factoryMethod.GetILGenerator();
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Newobj, ctor);
il.Emit(OpCodes.Ret);
return (Func<TArg1, TResult>)
factoryMethod.CreateDelegate(typeof(Func<TArg1, TResult>));
}
如果替换ldarg.1
,则不会引发异常newobj
带有ldnull
,因此问题一定是由这两条IL指令引起的。进一步的实验表明错误在于ldarg.1
。(对于上面的特定示例,我已将其替换为ldstr
)
有人看到这些IL指令有什么问题吗?此方法是静态的,因此它没有
此参数作为arg0
。更改il.Emit(操作码Ldarg_1)代码>通过il.Emit(操作码.Ldarg_0)代码>对我来说效果很好。您的动态方法似乎只有一个参数,而且是静态的。为什么要使用Ldarg\u 1
而不是Ldarg\u 0
?因为没有“this”参数(通常是0 arg),所以应该使用Ldarg_0。现在我自己也在问这个问题。愚蠢的我,我想我假设索引0处的参数总是保留给这个
对象引用,即使使用静态方法也是如此。当然,事实并非如此。谢谢你指出显而易见的问题!我在寻找一些非常复杂的错误原因,但不是这个…:-O
ConstructorInfo ctor = typeof(Uri).GetConstructor(new Type[] { typeof(string) });
Func<string, Uri> uriFactory = ctor.ToFactoryMethod<string, Uri>();
Uri uri = uriFactory.Invoke("http://www.example.com");