簡體   English   中英

獲取表達式樹中ParameterExpression的運行時值

[英]Getting run-time value of a ParameterExpression in a expression tree

我錯過了顯而易見的事項:如何在lambda表達式表達式樹中訪問參數的值?

場景:對於委托x,我動態創建一個lambda表達式,其表達式樹體與委托x具有相同的簽名。 在lamdba的主體內部,我做了一些驗證,檢查,記錄東西(這只是測試代碼,而不是生產),然后我用原始參數調用原始委托x。 如果委托具有返回值,則返回該值。

這非常有效(包括將參數傳遞給原始委托)。

但是如果我想訪問傳遞給delegate / lambda的原始參數值,我就會碰到一堵磚牆。

偽代碼:

var del = new Func<string, int>(_=> {return 42;});
var paramDefs = Array.ConvertAll<ParameterInfo, ParameterExpression>(del.Method.GetParameters(), _ => { return Expression.Parameter(_.ParameterType, _.Name); });
var variableTest = Expression.Variable(typeof(string), "str");

var expression = Expression.Block(
  new [] { variableTest },
  // this line assigns the actual run time value (which is what I need) of the parameter to the variable - but I cannot hardcode the index.
  //Expression.Assign(variableTest, paramDefs[0]) 
  // this line would assigns the ParameterExpression object (causing a run-time exception since the type of the variable is string) ... I need the _value_ of the first (or nth) parameter.
  Expression.Assign(variableTest, Expression.ArrayIndex(Expression.Constant(paramDefs), Expression.Constant(0)))
);
var lamdba = Expression.Lambda(del.GetType(), expression, "foo", paramDefs);
var del2 = lamdba.Compile() as Func<string, int>;
del2("this is a test");

看起來你混淆了表達式樹編譯器太多了(好吧,我也對這段代碼感到困惑)。 我可以看到你試圖做的事情:你從數組中獲得了一個元素,然后你決定遍歷數組。 但你不能做數組[ParameterExpression],所以你使用了ArrayIndex。 但...

但ArrayIndex實際上並沒有返回“字符串”。 它返回MethodCallExpression。 因此,在這個“賦值”表達式中,您實際上有ParameterExpression和MethodCallExpression。 ET編譯器非常智能,可以編譯這些表達式並嘗試分配結果。 但是MethodCallExpression的結果是ParameterExpression。 當你有paramDefs [0]時,你就有了ParameterExpression,編譯器可以處理它。 但是編譯嵌套表達式更難,並且完全不清楚是否真的想要編譯這個嵌套表達式。

您可以做的是自己編譯和調用MethodCallExpression,因此您將在Assign表達式中使用ParameterExpression(如前所述)。 它可能看起來像這樣:

// Replace Assign in your Block expression.
Expression.Assign(variableTest, Expression.Lambda<Func<ParameterExpression>>(Expression.ArrayIndex(Expression.Constant(paramDefs), Expression.Constant(0))).Compile()()),

但它在性能方面可能非常沉重(加上代碼很難看)。 所以,我堅持你把循環從表達式樹中拉出來的想法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM