Неправильное лямбда-выражение - необходимо вернуть логическое значение Func

У меня есть блок кода, который я скопировал с другого сайта, который используется для анализа выражений фильтра для BindingSourceView. Исходный код был создан для VS 2008 и более ранней платформы.net, однако он не работал с VS 2010 и.Net Framework V4, поскольку функция Expression.Lambda больше не возвращает функцию, которая может быть приведена правильно.

<T> = Note

public class PostfixExpressionToLambda<T>
{
    .
    .
    .

/// <summary>
/// This is the core function, it generates the Lambda.
/// </summary>
/// <param name="postfixExpression"></param>
/// <returns></returns>
private LambdaExpression GenerateExpressionFromPostfixList(IList<string> postfixExpression)
    {
        Stack<Expression> stack = new Stack<Expression>();
        Dictionary<String, ParameterExpression> parameters = new Dictionary<String, ParameterExpression>();
        List<ParameterExpression> parametersList = new List<ParameterExpression>();

        parametersList.Add(inputObj);
        Int32 i = 0;
        while (i < postfixExpression.Count)
        {
            String token = postfixExpression[i];
            //First of all check if is a name of a property of the object
            if (propertyNames.Any(p => p.Name == token))
            {
                stack.Push(Expression.Property(inputObj, token));
            }
            else if (IsMemberAccessOperator(token))
            {
                //Member access operator could advance the index. This because the syntax used to invoke a method
                //is not so good with postfix :) that because Name.Contains('xxx') becomes Name Contains . xxx because
                //parenthesis are used to precedence.
                ExecuteMemberAccessOperator(token, stack, postfixExpression, ref i);
            }
            else if (IsBinaryOperator(token))
            {
                ExecuteBinaryOperator(token, stack);
            }
            else if (IsUnaryOperator(token))
            {
                ExecuteUnaryOperator(token, stack);
            }
            else if (IsParameter(token))
            {
                ExecuteParameter(token, stack, parameters, parametersList);
            }
            else
            {
                stack.Push(Expression.Constant(token));
            }
            i++;
        }

    .
    .
    .

        Expression final = stack.Pop();
        if (stack.Count > 0) throw new ArgumentException("The postfix expression is malformed");
        return Expression.Lambda(final, parametersList.ToArray());
    }
    .
    .
    .
}

Строка, показанная выше, возвращает лямбда-выражение с типом String, а не с логическим типом. Изучая лямбда-значение, возвращается тип:

.Lambda #Lambda1<System.Func`2[Armada.DataModels.Note,System.String]>Armada.DataModels.Note $object) {    "[CorrespondenceCategoryID]=6" }

Вызывается из этого метода:

public Expression<Func<T, P1, RetType>> Execute<P1, RetType>(IList<String> postfixExpression)
    {
        LambdaExpression lambda = GenerateExpressionFromPostfixList(postfixExpression);
        return (Expression<Func<T, P1, RetType>>)lambda;
    }

который генерирует исключение, пытаясь привести выражение, возвращаемое к логическому типу, когда возвращаемое значение функции выражения было строкой. RetType= логическое. Исключение составляет:

Невозможно привести объект типа 'System.Linq.Expressions.Expression`1[System.Func`2[Armada.DataModels.Note,System.String]]' к типу 'System.Linq.Expressions.Expression`1[System.Func`2[Armada.DataModels.Note,System.Boolean]].

Я подумал, что простой способ исправить это - предоставить лямбда-функцию делегату, который я хотел бы вернуть (из предыдущего блока кода):

private LambdaExpression GenerateExpressionFromPostfixList<P1, RetType>(IList<string> postfixExpression)
{
    .
    .
    .
    return Expression.Lambda<Func<T, P1, RetType>>(final, parametersList.ToArray());
}

Однако во время выполнения эта последняя строка теперь выдает ошибку, указывающую, что

Неправильное количество параметров, предоставленных для лямбда-декларации

Анализируемая строка довольно проста: "[CorrespondenceCategoryID]=6"

Полученное выражение должно оцениваться для каждого объекта в списке, чтобы определить, какие из них должны быть включены в список источников привязки. Одиночный параметр имеет NodeType of Parameter и Type of Note (объект, который я пытаюсь отфильтровать.

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

1 ответ

Решение

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

Динамический Линк - Часть 1

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