2015-03-25 53 views
12

由於Xamarin.iOS在運行時不支持代碼生成,爲什麼Compile()和DynamicInvoke()會按預期工作?LambdaExpression.Compile()爲什麼在iOS(Xamarin)上工作?

例如,下面的代碼正常工作:

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代碼?

回答

12

在支持代碼生成的平臺上,使用基於Reflection.Emit的LambdaCompiler

如果不可用,則使用the interpreter解釋的表達式。例如,有些類可以解釋ConstantAdd

+0

我懷疑這樣的事情。這是記錄在任何地方? – 2015-03-27 03:33:24

+0

儘管您的答案有意義,但我想知道是否有參考文件或文檔證實了這一點。 – 2015-03-31 20:30:01

+0

@PhilippeLeybaert我找不到任何東西,這就是我查看源代碼的原因。 – svick 2015-03-31 20:56:26

2

The details of the Xamarin limitations are here.

你似乎並不在Reflection.Emit的命名空間,這是很大的禁忌要使用什麼。你的代碼必須仍然是AOT'd。否則,我會想象它不會工作。

但是已經有[native]開發者阻礙iOS靜態分析工具並繞過動態代碼限制的例子。我試圖找到文章,但找不到它。

無論如何,我認爲你的情況並不能證明這一點。你的代碼示例仍然是AOT編譯的。

但是你提出了一個非常好的問題:表達式在什麼時候被評估?

編輯:

另一個關於同一主題的SO回答:What does Expression.Compile do on Monotouch?

還有上Expression.Compile()和 「全AOT」 這裏一些好的信息: http://www.mono-project.com/docs/advanced/aot/

編輯: 在閱讀更多,我想我知道這裏發生了什麼。這並不是說Expression.Compile()不會工作 ...這是因爲當你的iOS應用程序包在提交到應用程序商店時受到iOS靜態分析工具的影響時,它不會通過分析,因爲它動態生成代碼。所以,當然,你可以使用Expression.Compile(),但不要期望它被接受進應用商店。但正如@svick所述,如果使用「完整的AOT」編譯選項,則表達式編譯()可能會在運行時失敗,甚至可能無法編譯。

+2

你是說'Expression'會是AOT嗎?考慮到'Expression'是在運行時構建的,這怎麼可能工作呢? – svick 2015-03-27 02:26:30

+0

@svick:另一個關於同一主題的SO回答似乎表明,在Xamarin.iOS應用程序中,表達式由AOT編譯器預編譯:http://stackoverflow.com/questions/24977939/what -does-expression-compile-do-on-monotouch – NovaJoe 2015-04-03 14:59:10

+0

@svick:要重新迭代,我的意思是我的理解是Expression不是在運行時使用Mono的AOT編譯器構建的。它是在編譯時建立的。 – NovaJoe 2015-04-03 15:18:11

相關問題