【发布时间】:2012-08-20 16:29:22
【问题描述】:
我有一个将构造函数包装在动态工厂方法中的方法:
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>));
}
但是,以下代码会在 .Invoke(…) 上抛出 VerificationException:
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");
如果我替换ldarg.1,则不会引发异常; newobj <ctor>和ldnull,所以问题肯定是这两条IL指令引起的。进一步的实验表明错误在于ldarg.1。 (对于上面的具体示例,我已将其替换为 ldstr <string>。)
有人看到这些 IL 指令有什么问题吗?
【问题讨论】:
-
您的动态方法似乎只有一个参数,并且是静态的。你为什么使用
Ldarg_1而不是Ldarg_0?由于没有“this”参数(通常是 0 arg),因此您应该使用 Ldarg_0。 -
我现在在问自己。愚蠢的我,我想我假设索引 0 处的参数总是为
this对象引用保留,即使使用静态方法也是如此。当然,事实并非如此。
标签: c# reflection reflection.emit dynamicmethod verificationexception