我很明顯缺少:如何訪問lambda表達式表達式樹中的參數值?在表達式樹中獲取參數表達式的運行時間值
場景:對於委託x我動態地創建一個lambda表達式,其表達式樹體具有與委託x相同的簽名。在lamdba的內部,我做了一些驗證,檢查,記錄東西(這只是測試代碼,而不是生產),然後用原始參數調用原始代表x。如果委託具有返回值,則也會返回該值。
工作得很好(包括將參數傳遞給原始代理)。
但是我打磚牆如果我想訪問傳遞給委託/ 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");
註釋掉的代碼似乎是正確的,所以我會這樣做。你說你不能硬編碼索引。爲什麼不?對我來說,就像那樣會工作得很好。 – 2010-03-09 20:58:10
我已經改變了代碼。我最初想要遍歷表達式樹(Expression.Loop)中的paramDefs,逐個訪問每個參數。由於代碼適用於任何委託類型,因此對索引進行硬編碼將無法工作。 我從表達式樹中抽取了循環構造。對於具有5個參數的委託,現在我只生成五個表達式(最簡單的情況是將每個參數值複製到一個對象[])。 但是,最初的問題仍然讓我感到困惑 - 是否有方法從ParameterExpression實例獲取實際值? – dalo 2010-03-09 21:36:55