Компиляция лямбд и вызов делегатов на устройстве в Monotouch - PullRequest
9 голосов
/ 23 июля 2011

Я в настоящее время портирую кодовую базу .NET в MonoTouch, и в настоящее время я работаю над методом, который получает Expression<T>. Я пытаюсь скомпилировать его, а затем динамически вызывать его.

Вот что я сделал:

// 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);

Это прекрасно работает в симуляторе iOS, результат "12" напечатан в моей консоли. Но потом я попробовал это на iPad и получил следующее исключение.

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)

Что я делаю не так и как я могу заставить это работать?

1 Ответ

11 голосов
/ 23 июля 2011

Не знаком с System.Linq.Expressions, но, вероятно, он включает генерацию кода во время выполнения.

В iOS нет JIT, весь код должен быть скомпилирован заранее. То же ограничение не применяется в симуляторе, поэтому ваш код работает там.

См. здесь .

Метод Compile() не поддерживается на устройстве iOS, поскольку устройство препятствует запуску механизма JIT. Сама компиляция реализована с использованием System.Reflection.Emit, и это, в свою очередь, требует работающего JIT. Поэтому приведенный выше код никогда не будет работать с деревьями выражений.

...