Можно ли создать дерево выражений, которое напрямую вызывает метод?Например, рассмотрим следующий метод:
public static int MyFunc(int a, int b)
{
return a + b;
}
Я хотел бы создать дерево выражений, которое вызывает MyFunc с параметрами a = 1 и b = 2.Один из способов сделать это с помощью отражения:
var c1 = Expression.Constant(1);
var c2 = Expression.Constant(2);
var expr = Expression.Call(typeof(Program).GetMethod("MyFunc"), c1, c2);
Однако это невыгодно, потому что отражение медленное и превращает то, что должно быть во время компиляции, во время выполнения.
Я мог бывместо этого используйте следующий подход:
Expression<Func<int, int, int>> lambda = (a, b) => MyFunc(a, b);
var expr = Expression.Invoke(lambda, c1, c2);
Но это все же не то, что я хочу, потому что он заключает метод в лямбда-выражение вместо непосредственного его вызова.
Хорошее решение может быть основанодля делегата, как это:
Func<int, int, int> del = Program.MyFunc;
var expr = Expression.Invoke(del, c1, c2);
К сожалению, это не компилируется, потому что del
является делегатом, а не выражением.Есть ли способ построить выражение из делегата?(Обратите внимание, что я знаю цель делегата во время компиляции, поэтому мне не нужна гибкость, описанная здесь: Деревья выражений и вызов делегата .)
НеРешение -delegate также подойдет, если оно вызывает целевой метод как можно более прямым образом.
Обновление: Это также работает, но все еще зависит от отражения:
Func<int, int, int> del = Program.MyFunc;
var expr = Expression.Call(del.Method, c1, c2);
По крайней мере, это более вероятно, чтобы поймать проблемы во время компиляции.Но он все равно платит за рефлексию во время выполнения, не так ли?