LambdaExpression.Compile()为什么在iOS(Xamarin)上工作?

问题描述:

由于Xamarin.iOS在运行时不支持代码生成,为什么Compile()和DynamicInvoke()会按预期工作?LambdaExpression.Compile()为什么在iOS(Xamarin)上工作?

例如,下面的代码正常工作:

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代码?

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

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

+0

我怀疑这样的事情。这是记录在任何地方? – 2015-03-27 03:33:24

+0

尽管您的答案有意义,但我想知道是否有参考文件或文档证实了这一点。 – 2015-03-31 20:30:01

+0

@PhilippeLeybaert我找不到任何东西,这就是我查看源代码的原因。 – svick 2015-03-31 20:56:26

The details of the Xamarin limitations are here.

你似乎并不在Reflection.Emit的命名空间,这是很大的禁忌要使用什么。你的代码必须仍然是AOT'd。否则,我会想象它不会工作。

但是已经有[native]开发者阻碍iOS静态分析工具并绕过动态代码限制的例子。我试图找到文章,但找不到它。

无论如何,我认为你的情况并不能证明这一点。你的代码示例仍然是AOT编译的。

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

编辑:

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

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

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

+2

你是说'Expression'会是AOT吗?考虑到'Expression'是在运行时构建的,这怎么可能工作呢? – svick 2015-03-27 02:26:30

+0

@svick:另一个关于同一主题的SO回答似乎表明,在Xamarin.iOS应用程序中,表达式由AOT编译器预编译:http://stackoverflow.com/questions/24977939/what -does-expression-compile-do-on-monotouch – NovaJoe 2015-04-03 14:59:10

+0

@svick:要重新迭代,我的意思是我的理解是Expression不是在运行时使用Mono的AOT编译器构建的。它是在编译时建立的。 – NovaJoe 2015-04-03 15:18:11