Получение значений параметров метода внутри деревьев выражений - PullRequest
6 голосов
/ 03 марта 2011

Я возился с деревьями выражений, но я немного застрял.

У меня есть это выражение:

Expression<Func<IX, int>> expr = i => i.GetAll(1, b, method());

Где:

int b = 2;

public static int method()
{
    return 3;
}

public interface IX
{
    int GetAll(int a, int b, int c);
}

Теперь я хочу получить имя метода и значения параметров для этого метода. Название метода простое, но значения параметров сложнее. Я знаю, что могу разобрать их сам, но мне нужно будет обработать все случаи (ConstantExpression, MemberExpression, MethodCallExpression и, возможно, больше, о которых я не знаю). Поэтому я подумал, есть ли «общий» способ получить свои ценности. например, 1, 2, 3.

Ответы [ 2 ]

8 голосов
/ 03 марта 2011

Вы можете получить аргументы рассматриваемых MethodCallExpression и создать из них скомпилированные Func<object> s (типы значений бокса, если необходимо), которые затем можно будет оценить.

Например:

var args = from arg in ((MethodCallExpression)expr.Body).Arguments
           let argAsObj = Expression.Convert(arg, typeof(object))
           select Expression.Lambda<Func<object>>(argAsObj, null)
                            .Compile()();

Это, очевидно, взорвется, если тело выражения не является выражением вызова метода или если какой-либо из аргументов метода не может быть оценен как есть (например, если они зависят от аргумента выражения).

Очевидно, что вы можете работать лучше, если заранее знаете типы аргументов метода.Для вашего конкретного примера это должно работать:

var args = from arg in ((MethodCallExpression)expr.Body).Arguments               
           select Expression.Lambda<Func<int>>(arg, null)
                            .Compile()();
1 голос
/ 03 марта 2011

Можете ли вы не просто получить все параметры, а затем скомпилировать и выполнить их?Я не понимаю, как можно было бы получить все значения без выполнения, если они могут быть вызовами методов.

...