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

Why does LambdaExpression.Compile() work on iOS (Xamarin)?

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

The details of the Xamarin limitations are here.

您似乎没有使用 Reflection.Emit 命名空间中的任何内容,这是最大的禁忌。您的代码必须仍然是 AOT。不然估计不行。

但是已经有 [本地] 开发人员阻挠 iOS 静态分析工具并规避动态代码限制的例子。我试图找到这篇文章,但找不到。

无论如何,我不认为你的场景说明了这一点。您的代码示例仍将是 AOT 编译的。

但是你提出了一个很好的问题:表达式在什么时候被求值?

编辑:

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

这里还有一些关于 Expression.Compile() 和 "full AOT" 的有用信息: http://www.mono-project.com/docs/advanced/aot/

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

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

如果这不可用,则使用 the interpreter. For example, there are classes that interpret Constant and Add.

解释 表达式