获取两个表达式<;谓词<;字符串>>;对象

本文关键字:lt gt 字符串 对象 谓词 表达式 两个 获取 | 更新日期: 2023-09-27 18:26:50

我需要将Expression>动态构建为Expression>对象的结合,例如

Expression<Predicate<string>> expression1 = c => c.Contains("aaa");
Expression<Predicate<string>> expression2 = c => c.Contains("bbb");

如何将这些表达式与AND运算符组合以获得另一个

Expression<Predicate<string>>

对象?

谢谢!

获取两个表达式<;谓词<;字符串>>;对象

var par = Expression.Parameter(typeof(string));
Expression<Predicate<string>> expression3 = 
    Expression.Lambda<Predicate<string>>(
        Expression.AndAlso(
            Expression.Invoke(expression1, par), 
            Expression.Invoke(expression2, par)), 
        par);
Predicate<string> method1 = expression3.Compile();
Console.WriteLine(method1("aaa"));
Console.WriteLine(method1("bbb"));
Console.WriteLine(method1("aaabbb"));

我们必须创建一个新的表达式。par是参数。然后,我们使用Expression.Invoke来调用"旧"表达式(并传递par作为它们的参数)。然后我们使用Expression.AndAlso来制作&&表达式。最后,我们使用Expression.Lambda<Predicate<string>>创建最终表达式(最后一个参数,par是lambda表达式的参数名称)

注意(常见错误)Expression.And&,而Expression.AndAlso&&(与Expression.Or*相同)

您基本上会使用PredicateBuilder,但使用Predicate而不是它使用的Func<T, bool>

public static Expression<Predicate<string>> And(this Expression<Predicate<string>> expr1,
                                                Expression<Predicate<string>> expr2)
{
    var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
    return Expression.Lambda<Predicate<string>>
            (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);
}

如果您不介意使用Func<string, bool>而不是Predicate,那么您可以直接使用PredicateBuilder。

Expression<Predicate<string>> expression1 = c => c.Contains("aaa") && c.Contains("bbb");

以上内容将起作用,而且应该始终是可能的。然而,如果您出于某种原因试图将这些谓词进行一般性组合,请尝试以下操作:

Expression<Predicate<string>> expression1 = c => c.Contains("aaa");
Expression<Predicate<string>> expression2 = c => c.Contains("bbb");
Expression<Predicate<string>> expression3 = Expression.AndAlso(expression1.body , expression2.body); 

此外,以下是它的文档:http://msdn.microsoft.com/en-us/library/bb353520.aspx您会发现Expression 的其他类似有用的成员