由于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代码?
答案 0 :(得分:13)
在支持代码生成的平台上,使用了基于Reflection.Emit的LambdaCompiler
。
如果没有,表达式使用the interpreter解释。例如,有些类可以解释Constant
和Add
。
答案 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()可能会在运行时失败,或者甚至可能无法编译。