3

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?

stakx - no longer contributing
  • 83,039
  • 20
  • 168
  • 268
  • 1
    Your dynamic method seems to only have one parameter, and is static. Why are you using `Ldarg_1` instead of `Ldarg_0`? Since there is no "this" parameter (which usually is the 0 arg), you should use Ldarg_0. – vcsjones Aug 20 '12 at 16:36
  • I'm asking that myself, now. Silly me, I guess I assumed that the argument at index 0 were always reserved for the `this` object reference, even with static methods. Which is not the case, of course. – stakx - no longer contributing Aug 20 '12 at 18:59

1 Answers1

6

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.

Marcelo De Zen
  • 9,439
  • 3
  • 37
  • 50