为什么LambdaExpression.Compile()适用于iOS(Xamarin)?

时间:2015-03-25 00:42:57

标签: ios xamarin il

由于Xamarin.iOS不支持在运行时生成代码,为什么Compile()和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代码?

2 个答案:

答案 0 :(得分:13)

在支持代码生成的平台上,使用了基于Reflection.Emit的LambdaCompiler

如果没有,表达式使用the interpreter解释。例如,有些类可以解释ConstantAdd

答案 1 :(得分:2)

The details of the Xamarin limitations are here.

你似乎没有在Reflection.Emit命名空间中使用任何东西,这是最大的禁忌。您的代码仍必须是AOT。否则,我认为它不起作用。

但是有一些[本机]开发人员阻止iOS静态分析工具并绕过动态代码限制的例子。我试图找到这篇文章,但找不到它。

无论如何,我不认为你的场景就是例证。您的代码示例仍将是AOT编译的。

但是你提出了一个非常好的问题:在什么时候评估表达式?

修改

关于同一主题的另一个答案:What does Expression.Compile do on Monotouch?

这里还有一些关于Expression.Compile()和“完整AOT”的好信息: http://www.mono-project.com/docs/advanced/aot/

修改 在阅读了更多内容之后,我想我知道这里发生了什么。并不是说Expression.Compile()不会工作 ...当你的iOS应用程序包在提交给app商店时受到iOS静态分析工具的影响时,它就不会通过分析,因为它是动态生成代码。所以,当然,您可以使用Expression.Compile(),但不要指望它被接受到应用商店中。但正如@svick所提到的,如果你使用“完整的AOT”编译选项,你的Expression.Compile()可能会在运行时失败,或者甚至可能无法编译。