I have this method which wraps a constructor in a dynamic factory method:
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>));
}
However, the following code throws a VerificationException
on the .Invoke(…)
:
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");
The exception isn't thrown if I replace ldarg.1
; newobj <ctor>
with ldnull
, so the problem must be caused by these two IL instructions. Further experiments suggest that the error lies with ldarg.1
. (I've replaced this with a ldstr <string>
for the specific example above.)
Does anyone see what's wrong with these IL instructions?
This method is static, so it doesn't have a this
parameter as arg0
. Changing il.Emit(OpCodes.Ldarg_1);
by il.Emit(OpCodes.Ldarg_0);
worked fine for me.