views:

37

answers:

2

Is something like this possible?

//
//  create a delegate
Action<Type> action = (t) => t.DoSomething;

//
// get the IL generator for a method
ILGenerator il = myMethodBuilder.GetILGenerator();

//
// try and call the delegate
il.EmitCall(OpCodes.Callvirt, action.Method, null);

Im getting a MethodAccessException whenever I try to invoke the method.

Thanks

+3  A: 

Im getting a MethodAccessException whenever I try to invoke the method.

This is because the method generated for the C# (t) => t.DoSomething lambda is private. Chances are this lambda won't be static, either, depending on which of the local variables it captures from the outer method. You're issuing a callvirt instruction but you don't appear to be supplying an instance.

You can verify this by loading your application's code in Reflector and looking at the implementation of your (t) => t.DoSomething lambda.

You need to either:

  • Upgrade your lambda to a real public static method in an externally-visible class
  • Find a way to include a parameter of type Action<Type> in your IL method, generate code that calls Action<Type>.Invoke, then pass your action variable into the generated method
Tim Robinson
I can see the MethodInfo IsPrivate is true, is there a way to change this? Otherwise I can just use a Public static member, but its neater with a Lambda :)Thanks
James Simpson
There's no way to change this; it's an implementation detail of the C# compiler
Tim Robinson
Thinking about this further, your better option might be to find a way to pass the `action` delegate into your generated method, either by adding a parameter, or by making your generated method an class instance member and setting a field on that class. Because you'd be calling your lambda through a delegate, you won't be sensitive to how that lambda is implemented.
Tim Robinson
Yea, that seems to be a solution, thanks! I would vote this up, but cant! doh
James Simpson
You could mark it as accepted :p. (Provided my suggestion works, of course.)
Tim Robinson
A: 

See if this is related to what is mention Here.

VoodooChild