Выражения... Что я делаю не так?

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

Вот мой код

Expression<Func<int,int,int>> addExpr = (x, y) => x + y;
var p1 = Expression.Parameter(typeof(int), "p1");
var p2 = Expression.Parameter(typeof(int), "p2");
var lambda = Expression.Lambda<Func<int,int,int>>(addExpr, p1, p2); //<-here
var del = lambda.Compile();
var result = del(2,3); //expect 5

но это вызывает исключение ArgumentException: выражение типа 'System.Func`3[System.Int32,System.Int32,System.Int32]' нельзя использовать для возвращаемого типа 'System.Int32'

по линии, указанной выше. Что я сделал не так?

3 ответа

Решение

Вы должны обернуть addExpr в вызове с использованием параметров выражения

Expression<Func<int,int,int>> addExpr = (x, y) => x + y;
var p1 = Expression.Parameter(typeof(int), "p1");
var p2 = Expression.Parameter(typeof(int), "p2");
var invokeExpression=Expression.Invoke(addExpr,p1,p2);
var lambda = Expression.Lambda<Func<int,int,int>>(invokeExpression,p1,p2);
var del = lambda.Compile();
var result=del(2,3);

Вызов - это то, как вы набираете p1 к x и p2 к y, в качестве альтернативы вы можете просто написать выше как

var p1 = Expression.Parameter(typeof(int), "p1");
var p2 = Expression.Parameter(typeof(int), "p2");
var lambda=Expresion.Lambda<Func<int,int,int>>(Expression.Add(p1,p2),p1,p2);
var del = lambda.Compile();
var result=del(2,3);

В противном случае вам нужно захватить тело выражения в лямбду и передать параметры выражения.

var lambda=Expresion.Lambda<Func<int,int,int>>(addExpr.Body,addExpr.Parameters);

Ваш код должен быть:

var lambda = Expression.Lambda<Func<Expression<Func<int, int, int>>, int, int>(addExpr, p1, p2);

Ваш текущий код ожидает int и ваше прохождение в Expression<Func<int, int, int>>,

Обновить

На самом деле вышеупомянутое не скомпилируется, вам нужно сделать:

var lambda = Expression.Lambda<Func<int, int, int>>(Expression.Add(p1, p2), p1, p2);

Вы должны разложить addExprтело или желательно просто написать это с нуля, т.е. Expression.Add(p1,p2) вместо addExpr,

Другие вопросы по тегам