@DancingOnWater

Что не так с Lambdaexpression, созданного из BinaryExpression?

В ходе разбора темы древа выражений в C# возник такой вопрос, который лучше всего демонстрирует этот код
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

class Program
{
    static void Main()
    {
        List<int> corrections = new List<int>{1,2,3};
        Expression<Func<int, bool>> previousExpression = x=> x == corrections[0];

        Expression<Func<int, bool>> filterFunctor, comparison = x=> x == corrections[1] || x == corrections[0];
        Expression<Func<int, bool>> currentExpression = x => x == corrections[1];
        var result = Expression.OrElse(currentExpression.Body, previousExpression.Body);
        filterFunctor = Expression.Lambda<Func<int, bool>>(result, previousExpression.Parameters.Single() );
                
        Console.WriteLine( filterFunctor.Compile());
        Console.WriteLine( comparison.Compile() );

    }
}

comparison легко и просто скомпилиркется, а вот filterFunctor выкинет исключение
[ERROR] FATAL UNHANDLED EXCEPTION: System.InvalidOperationException: variable 'x' of type 'System.Int32' referenced from scope '', but it is not defined

И мне совершенно не понятно, что это значит, как оно возникло и как исправлять.
  • Вопрос задан
  • 329 просмотров
Решения вопроса 1
Nipheris
@Nipheris Куратор тега C#
'x' в previousExpression и 'x' в currentExpression считаются разными переменными. Необходимо явно указать, что одну из лямбд, например currentExpression, нужно вызывать с той же переменной, что и другую. Например, попробуйте так:

var result = Expression.OrElse(Expression.Invoke(currentExpression, previousExpression.Parameters[0]), previousExpression.Body);


И да, могли бы привести в порядок код, прежде чем вопрос задавать, минут 10 я только пытался понять что вы делаете. Вот как вы считаете, это строчка легко читается?
Expression<Func<int, bool>> filterFunctor, comparison = x=> x == corrections[1] || x == corrections[0];

Помимо того, что вы лямбду в скобки не берете, вы еще и две переменных в одном стейтменте объявляете.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы