所以 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时会发生什么?是抛出和异常,如果有的话是什么异常?它是否记录在任何地方?
答案 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)而且另一种语言(因为解释的内部结构是另一种语言),它包含一个解释器。这是为什么我觉得这是一个有趣的项目的一个重要原因:)