2014-07-27 28 views
8

所以 Expression.Compile執行以下Expression.Compile在Monotouch上做了什麼?

編譯由表達式樹描述成可執行代碼lambda表達式和產生表示lambda表達式的委託。

它在便攜式類庫中可用。

然而通過MonoTouch的dynamic code generation is not supported

運行.NET當由於iPhone的內核防止生成代碼的應用程序動態地單聲道在iPhone上不支持任何形式的動態代碼生成的。

所以基於Xamarin on IOS不支持Expression.Compile。

那麼當你在IOS上調用Expression.Compile Xamarin會發生什麼?它是否拋出異常,如果有,是什麼例外?它在任何地方都有記錄嗎?

回答

4

該代碼是用AOT選項編譯的,所以它實際上不會在運行時編譯(我不知道在Compile())後臺發生的細節。微軟文檔中的例子在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)); 
    } 

你不能在運行時創建(System.Reflection.Emit)IL代碼,也有使用具有特定連接器選項的反思,some more info on this thread.有可能是不AOT編譯表達式和你將這些情況限制在運行時得到一個異常,試圖用AOT-only選項進行JIT編譯。

+1

可能編寫的表達式不可能在編譯時編譯,而且它們仍然可以與Xamarin.iOS一起使用。我懷疑他們被編譯成可以解釋的東西。 –

1

如果你看一看,新的Compile(bool)重載可能會使這個更清晰,儘管文檔沒有(當前)提供關於細節的很多信息。

Compile()用於始終執行IL生成,因此不適用於AOT。 Compile()現在也可以對代表操作的一組對象進行「編譯」(它們的操作與IL非常類似,具有由固定長度object[]表示的堆棧) ,它使用反射(但不是`Reflection.Emit'反射)來進行方法調用,並使用自己的代碼來執行基本操作,如算術。讓我們請求IL代(假)或解釋(真),但它被視爲偏好而不是需求;如果你只在一個只有解釋的平臺上詢問IL代,你會得到解釋,反之亦然。大多數情況下,如果你可以做任何你想要的IL代(通常更快,並且對解釋器有一些限制),但是你可能想排除平臺之間存在差異,或者你可能會發現平均而言,解釋代表比較慢平均執行Compile()步驟本身對於解釋程序來說速度更快,有時如果要創建多個一次性表達式,解釋程序的總時間會更快。 (但並非總是,如果您出於性能原因嘗試此操作,則可以使用配置文件和/或考慮緩存代表)。

這意味着System.Linq.Expressions包含代表一種語言(表達式本身就是一種語言)的代碼,寫在第二個(C#)中,它們不僅被編譯成第三種語言(CIL),還被編譯成另一種語言語言(因爲解釋的內部結構是另一種語言),它包含一個解釋器。這是爲什麼我覺得它是一個有趣的項目的重要組成部分:)