Compiling lambdas and invoking delegates on the de

2020-06-13 06:10发布

问题:

I am currently porting a .NET codebase in MonoTouch and I'm currently working on a method that receives an Expression<T>. I'm trying to compile it, and then dynamically invoke it.

Here's what I did:

// Here's an example of what I could receive
Expression<Action<int>> expression = (a => Console.WriteLine (a * 2));

// And here's what I'm trying to do to invoke it
expression.Compile().DynamicInvoke(6);

This works fine in the iOS Simulator, the result "12" is printed in my console. But then I tried it on an iPad, and I received the following exception.

Object reference not set to an instance of an object
   at System.Linq.jvm.Runner.CreateDelegate ()
   at System.Linq.Expressions.LambdaExpression.Compile ()
   at System.Linq.Expressions.Expression`1[System.Action`1[System.Int32]].Compile ()
   at TestSolution2.AppDelegate.FinishedLaunching (MonoTouch.UIKit.UIApplication app, MonoTouch.Foundation.NSDictionary options)

What am I doing wrong and how could I make it work?

回答1:

Not familiar with System.Linq.Expressions, but presumably it involves runtime code generation.

There is no JIT in iOS, all code must be compiled ahead-of-time. The same restriction does not apply in the simulator, hence your code runs there.

See here.

The Compile() method is not supported on the iOS device, since the device prevents the JIT engine from running. Compile itself is implemented using System.Reflection.Emit and this in turns requires a functioning JIT. So the above code would never wor kwith expression trees.