Expression.Compile在Monotouch上做了什么?

因此Expression.Compile执行以下操作

将表达式树描述的lambda表达式编译为可执行代码,并生成表示lambda表达式的委托。

它可以在Portable Class Libraries中找到。

但是,当通过Monotouch运行.net时, 不支持动态代码生成

由于iPhone的内核阻止应用程序动态生成代码,因此iPhone上的Mono不支持任何forms的动态代码生成。

所以基于IOS的Xamarin不能支持Expression.Compile。

那么当您在IOS上调用Expression.Compile Xamarin时会发生什么? 它是抛出还是exception,如果有的话是什么exception? 它是否记录在任何地方?

代码是使用AOT选项编译的,因此它实际上不会在运行时编译(我不知道在Compile()后台发生的细节)。 Microsoft文档中的示例在iOS设备上运行正常,没有例外。

public override void FinishedLaunching(UIApplication application) { System.Linq.Expressions.Expression> expr = i => i < 5; // Compile the expression tree into executable code. Func deleg = expr.Compile(); // Invoke the method and print the output. Console.WriteLine("deleg(4) = {0}", deleg(4)); } 

您无法在运行时创建IL代码(System.Reflection.Emit),并且对某些链接器选项使用Reflection也存在限制,此线程上还有一些更多信息。 可能存在不进行AOT编译的表达式,在这些情况下,您将在运行时获得有关尝试使用仅AOT选项进行JIT编译的exception。

如果你看一下,新的Compile(bool)重载可能会使这个更清晰,尽管文档(目前)没有提供有关细节的大量信息。

Compile()过去总是进行IL生成,因此不适用于AOT。

有一段时间了(我忘了它进来的时候) Compile()现在也可以对表示操作的一组对象进行“编译”(它们的操作与IL非常相似,堆栈由固定长度的object[] ) ,它使用reflection(但不是`Reflection.Emit’reflection)进行方法调用,并使用自己的代码进行算术等基本操作。

Compile(bool)让你问IL生成(错误)或解释(真实),但它被视为偏好而不是需求; 如果你在只有解释的平台上要求IL生成,你会得到解释,反之亦然。 大多数情况下,如果你可以做任何一个你想要IL生成(通常更快,并且对解释器有一些限制)但你可能想要排除平台之间存在差异,或者你可能会发现平均而言解释的委托更慢到执行,平均而言, Compile()步骤本身对于解释器来说更快,有时如果你创建了几个一次性表达式,那么解释器的总时间会更快。 (但并非总是如此,如果您出于性能原因尝试此操作,请查看配置文件和/或考虑缓存代理)。

这意味着System.Linq.Expressions包含代表一种语言的代码(表达式本身就是一种语言),用第二种语言编写(C#),它们不仅编译成第三种语言(CIL)而且还编译成另一种语言。语言(因为解释的内部结构是另一种语言),它包含一个解释器。 这是为什么我觉得这是一个有趣的项目贡献的重要部分:)