Почему LambdaExpression.Compile() работает на iOS (Xamarin)?
Так как Xamarin.iOS не поддерживает генерацию кода во время выполнения, почему компиляция() и DynamicInvoke() работают должным образом?
Например, следующий код работает нормально:
var lambda = Expression.Lambda(
Expression.Add(
Expression.Constant(1),
Expression.Constant(2)
)
);
var f = lambda.Compile();
var result = f.DynamicInvoke();
// result==3 at this point
Является ли Xamarin вычислением дерева выражений во время выполнения вместо испускания кода IL?
Ответы
Ответ 1
На платформах, поддерживающих генерацию кода, используется LambdaCompiler
на основе Reflection.Emit.
Если это не доступно, выражение интерпретируется с помощью интерпретатора. Например, существуют классы, которые интерпретируют Constant
и Add
.
Ответ 2
Подробности ограничений Xamarin приведены здесь.
Кажется, что вы не используете что-либо в пространстве имен Reflection.Emit, которое является большим no-no. Ваш код должен быть AOT'd. В противном случае я бы предположил, что это не сработает.
Но там были примеры [родных] разработчиков, пресекающих инструмент статического анализа iOS и обход ограничений динамического кода. Я попытался найти статью, но не смог ее найти.
В любом случае, я не думаю, что ваш сценарий иллюстрирует это. Ваш пример кода по-прежнему будет скомпилирован AOT.
Но вы поднимаете действительно хороший вопрос: в какое время оценивается выражение?
EDIT:
Другой ответ SO по той же теме: Что делает Expression.Compile в Monotouch?
Здесь также есть хорошая информация о Expression.Compile() и "full AOT" здесь:
http://www.mono-project.com/docs/advanced/aot/
EDIT:
Прочитав еще несколько, я думаю, что знаю, что происходит здесь. Это не значит, что Expression.Compile() не будет работать... это то, что когда ваш пакет приложений iOS подвергается инструменту статического анализа iOS, когда вы отправляете его в хранилище приложений, он не пройдет анализ, потому что он динамически генерирующий код. Итак, вы можете использовать Expression.Compile(), но не ожидайте, что он будет принят в хранилище приложений. Но, как упоминалось в @svick, если вы используете параметр компиляции "полный AOT", ваш Expression.Compile(), вероятно, завершится неудачно во время выполнения или, возможно, даже скомпилирует компиляцию.