Brakuje mi oczywistego: Jak uzyskać dostęp do wartości parametru w drzewie wyrażenia wyrażenia lambda?Uzyskiwanie wartości czasu działania parametru ParameterExpression w drzewie wyrażeń
Scenariusz: Dla delegata x dynamicznie tworzę wyrażenie lambda z ciałem drzewa wyrażeń, które ma ten sam podpis co delegat x. Wewnątrz ciała lamdby dokonuję sprawdzania poprawności, sprawdzania, rejestrowania danych (to jest tylko testowanie kodu, a nie produkcji), a następnie przywołuję oryginalnego delegata x z oryginalnymi parametrami. Jeśli delegat ma wartość zwracaną, również zostanie zwrócona.
To działa całkiem dobrze (w tym przekazywanie parametrów oryginalnemu uczestnikowi).
Ale uderzam w ceglaną ścianę, jeśli chcę uzyskać dostęp do oryginalnych wartości parametrów przekazanych do delegata/lambda.
pseudokod:
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");
Kod z komentarzem wydaje się być poprawny, więc zrobiłbym to. Mówisz, że nie możesz twardo kodować indeksu. Dlaczego nie? Wydaje mi się, że to będzie dobrze. –
Od tego czasu zmieniłem kod. Początkowo chciałem zapętlić wartości paramDefs w drzewie wyrażeń (Expression.Loop), odwiedzając każdy parametr jeden po drugim. Ponieważ kod działa na dowolnym typie pełnomocnika, twarde kodowanie indeksu nie zadziałałoby. Wyciągnąłem konstrukcję pętli z drzewa wyrażeń. Dla delegata z 5 parametrami, po prostu generuję pięć wyrażeń (najprostszym przypadkiem jest kopiowanie wartości każdego parametru do obiektu []). Jednak początkowe pytanie nadal mnie niepokoi - czy istnieje sposób na uzyskanie rzeczywistej wartości z instancji ParameterExpression? – dalo