2013-02-18 60 views
3

我試圖找出如何創建一個調用具有基準參數的方法的表達。如何調用參考變量的方法與表達式樹

讓我解釋一下我用一個簡單的(但人造的)例子問題。考慮方法:

public static int TwiceTheInput(int x) 
    { 
     return x*2; 
    } 

我可以創造一個表達的做類似調用上述方法:

{ 
     var inputVar = Expression.Variable(typeof (int), "input"); 
     var blockExp = 
      Expression.Block(
        new[] {inputVar} 
        , Expression.Assign(inputVar, Expression.Constant(10)) 
        , Expression.Assign(inputVar, Expression.Call(GetType().GetMethod("TwiceTheInput", new[] { typeof(int) }), inputVar)) 
        , inputVar 
        ); 
     var result = Expression.Lambda<Func<int>>(blockExp).Compile()(); 
    } 

在執行過程中,「結果」上面應該結束了,20的值。 現在考慮一個版本,使用由基準參數TwiceTheInput()的:

public static void TwiceTheInputByRef(ref int x) 
    { 
     x = x * 2; 
    } 

我怎樣寫一個類似的表達式樹調用TwiceTheInputByRef(),並通過參照它的參數?

解決方案:(感謝蟬)。用途:

Type.MakeByRefType() 

這裏有一個代碼段生成表達式樹:

 { 
     var inputVar = Expression.Variable(typeof(int), "input"); 
     var blockExp = 
      Expression.Block(
        new[] { inputVar } 
        , Expression.Assign(inputVar, Expression.Constant(10)) 
        , Expression.Call(GetType().GetMethod("TwiceTheInputByRef", new[] { typeof(int).MakeByRefType() }), inputVar) 
        , inputVar 
        ); 
     var result = Expression.Lambda<Func<int>>(blockExp).Compile()(); 
    } 
+2

您是否嘗試過使用lambda表達式調用相同的方法,讓C#編譯器將其轉換爲表達式樹,然後進行反編譯?這通常是我做的如何構建表達樹:) – 2013-02-18 15:55:26

+0

不,我沒有做過。任何通過示例演示的網址? – DPrb 2013-02-18 16:02:48

回答

3

您沒有太大變化,只是刪除Assign,改變typeof(int)typeof(int).MakeByRefType()

var blockExp = Expression.Block(
    new[] { inputVar } 
    , Expression.Assign(inputVar, Expression.Constant(10)) 
    , Expression.Call(
     typeof(Program).GetMethod( 
      "TwiceTheInputByRef", new [] { typeof(int).MakeByRefType() }), 
     inputVar) 
    , inputVar 
); 
+0

謝謝。這樣可行。 – DPrb 2013-02-18 16:24:47

+0

不要回想起我的頭頂,但可以在這裏使用(半未記錄的)__makeref關鍵字嗎?自然,你需要一個實際的變量。 – JerKimball 2013-02-18 16:36:38

+0

@JerKimball正如你所說的,'__makeref'對變量有效,而不是類型,所以我們不能在這裏使用它。請注意,'MakeByRefType'部分僅由'GetMethod'用來解決'TwiceTheInputByRef'的適當重載:如果沒有超載,那麼第二個參數是多餘的。 – 2013-02-18 16:41:05