获取两个表达式<;谓词<;字符串>>;对象
本文关键字: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 的其他类似有用的成员