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

为什么LambdaExpression.Compile()在iOS(Xamarin)上工作?,ios,xamarin,il,Ios,Xamarin,Il,既然Xamarin.iOS不支持在运行时生成代码,为什么Compile()和DynamicInvoke()会按预期工作 例如,以下代码可以正常工作: var lambda = Expression.Lambda( Expression.Add( Expression.Constant(1), Expression.Consta

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

您似乎没有在Reflection.Emit命名空间中使用任何东西,这是一个很大的禁忌。您的代码必须仍然是AOT。否则的话,我想这是行不通的

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

不管怎样,我不认为你的场景能说明这一点。您的代码示例仍将进行AOT编译

但是您提出了一个非常好的问题:表达式在什么时候被计算

编辑:

关于同一主题的另一个答案是:

这里还有一些关于Expression.Compile()和“完整AOT”的好信息:

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

在支持代码生成的平台上,会使用Reflection.Emit-based


如果不可用,则使用解释表达式。例如,有一些类可以解释和。

您是说
表达式将是AOT吗?考虑到
表达式
是在运行时构建的,这怎么可能起作用?@svick:关于同一主题的另一个答案似乎表明,正如我所说,表达式在Xamarin.iOS应用程序中由AOT编译器预编译:@svick:重新迭代,我想说的是,我的理解是,当您使用Mono的AOT编译器时,表达式不是在运行时构建的。它是在编译时构建的。我的观点是这是不可能的,因为表达式可以依赖于只有在运行时才知道的东西。另一个答案几乎只是说“它有效”,然后提出一些未经证实的声明。如果我读对了文档,它似乎说
Expression.Compile()
不应该与完整的AOT一起工作。我怀疑是这样的。这在任何地方都有记录吗?虽然你的答案有道理,但我想知道是否有参考或文档证实了这一点。@PhilippeLeybaert我找不到任何,这就是我查看源代码的原因。在Mono/Xamarin中,表达式不会被解释。它将提前编译(AOT)@诺瓦乔,我相信你错了。您引用的文档明确指出,AOT在“已知限制”下不支持
Expression.Compile