Expression.Compile在Monotouch上做了什么?

时间:2014-07-27 04:35:29

标签: c# xamarin.ios xamarin expression

所以 Expression.Compile执行以下操作

  

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

它可以在Portable Class Libraries中使用。

但是,当通过Monotouch dynamic code generation is not supported

运行.net时
  

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

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

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

2 个答案:

答案 0 :(得分:3)

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

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

您无法在运行时创建IL代码(System.Reflection.Emit),并且对某些链接器选项使用Reflection也有限制,some more info on this thread.可能存在不进行AOT编译的表达式,在这种情况下,您可以在运行时获取有关尝试使用仅AOT选项进行JIT编译的异常。

答案 1 :(得分:2)

如果您查看一下,新的Compile(bool)重载可能会让您更清楚,尽管文档(目前)没有提供有关详细信息的详细信息。

Compile()以前总是进行IL生成,因此无法使用AOT。

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

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

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