替代

2017-01-07 136 views
12

我現在移植使用表達式.Net Core應用程序的一些庫,遇到了我所有的邏輯是基於LambdaExpression.CompileToMethod這簡直是在缺少一個問題,下面是示例代碼:替代

public static MethodInfo CompileToInstanceMethod(this LambdaExpression expression, TypeBuilder tb, string methodName, MethodAttributes attributes) 
{ 
    ... 

    var method = tb.DefineMethod($"<{proxy.Name}>__StaticProxy", MethodAttributes.Private | MethodAttributes.Static, proxy.ReturnType, paramTypes); 
    expression.CompileToMethod(method); 

    ... 
} 

是否有可能以某種方式重寫它,以便使用表達式生成方法成爲可能?我已經可以用Emit做到這一點,但它非常複雜,我想避免它用於高級表達式。

我試圖用var method = expression.Compile().GetMethodInfo();但在這種情況下,我得到一個錯誤:

System.InvalidOperationException : Unable to import a global method or field from a different module.

我知道我可以手動發出IL,但我需要準確地轉換Expression - >到MethodInfo綁定到特定TypeBuilder代替建立我自己DynamicMethod就可以了。

+1

哇,試圖回答這個問題,我剛剛發現,.net核心缺乏文檔,沒有簡單的方法來找出什麼被取代什麼...運氣好的端口... –

+0

@LucasCorsaletti我認爲提供這樣的文檔是非常困難的,因爲我猜即使.net核心團隊也不知道什麼被替換了:)無論如何,謝謝你的嘗試 –

+0

有趣的是,我正在看這個問題。剛剛嘗試使用Linq.Expressions和最近的舊.NET 4.5創建類/實例方法。動態方法可以創建爲實例方法,與可見性屬性相關,但需要Reflection.Emit。使用Linq.Expressions構建它更具可讀性,但它不能用作實例方法。然而,我可以無恥地訪問內部和私有,使得與實例方法相同的功能成爲可能。我只是一個運行時代碼生成的初學者... –

回答

5

它不是一個理想的解決方案,但如果你不想寫一切從劃痕這是值得考慮:

  1. 如果你看看CompileToMethod實現,你會看到它使用引擎蓋下內部LambdaCompiler類。
  2. 如果你挖得更深,你會發現LambdaCompiler使用System.Reflection.Emit將lambda轉換爲MethodInfo
  3. System.Reflection.Emit受.NET Core支持。
  4. 考慮到這一點,我的建議是嘗試重用LambdaCompiler源代碼。你可以找到它here

這種解決方案的最大的問題是:

  1. LambdaCompiler的許多文件中傳播,因此它可能是麻煩找什麼是需要編譯它。
  2. LambdaCompiler可能會使用某些根本不受.NET Core支持的API。

補充幾點意見:

  1. 如果你想檢查哪些API是由平臺使用.NET API Catalog支持。
  2. 如果您想查看.NET標準版本之間的差異,請使用this網站。
+0

在提出問題之前,我反編譯了'CompileToMethod',但是當我發現'LambdaCompiler'是內部的時候我停止了。但是,現在我有了一個想法,我們可以通過反射調用一些內部方法。 *不,食肉動物,不要吃我([你有玩笑](https://xkcd.com/292/))*我會做一些研究並返回結果,並標記這個答案,如果沒有其他人想幫助我們。 –

+0

所以我在這裏。由於未知的原因,'.Net Standard'缺少構造函數'LambdaCompiler(AnalyzedTree tree,LambdaExpression lambda,MethodBuilder method)'。沒有理由不提供它,因爲'MethodBuilder'在另一個重載中使用,所以每個必需的程序集都被引用。我想我應該在某個存儲庫(corefx?)上發佈一個問題。目前,我想創建一個解決這個問題的拉取請求,但不確定回購。 –

+0

查看'corefx'源文件後,我發現它是通過'FEATURE_COMPILE_TO_METHODBUILDER'標誌故意執行的。不過,不知道爲什麼。 –