正文

.NET中lambda表达式合并问题及解决方法

文章摘要

该文章介绍了如何通过扩展表达式来实现逻辑与(And)和或(Or)的合并。文章定义了`ExpressionExtension`类,其中包含两个静态方法:`AndAlso`和`OrElse`。这两个方法用于合并多个表达式,生成逻辑与或或的扩展表达式。`AndAlso`方法逐个合并表达式,并使用`GetReplaceExpressionVisitor`来替换参数,最后返回一个Lambda表达式。`OrElse`方法的功能与`AndAlso`相似,但用于逻辑或运算。文章还定义了构建 visitor 的方法`GetReplaceExpressionVisitor`,用于处理参数替换。文章的核心内容是通过这些方法实现对表达式的扩展和逻辑运算的处理。

 /// <summary> /// 表达式扩展 /// </summary> public static class ExpressionExtension { /// <summary> /// 使用AndAlso合并表达式 /// </summary> /// <param name=”exprs”></param> /// <returns></returns> public static Expression<T> AndAlso<T>(this IList<Expression<T>> exprs) { if (exprs.Count==0) return null; if (exprs.Count==1) return exprs[0]; var leftExpr=exprs[0]; var left=leftExpr.Body; for (int i=1; i < exprs.Count; i++) { var expr=exprs[i]; var visitor=GetReplaceExpressionVisitor(expr.Parameters, leftExpr.Parameters); var right=visitor.Visit(expr.Body); left=Expression.AndAlso(left, right); } return Expression.Lambda<T>(left, leftExpr.Parameters); } /// <summary> /// 使用AndAlso合并表达式 /// </summary> /// <typeparam name=”T”></typeparam> /// <param name=”left”></param> /// <param name=”right”></param> /// <returns>left AndAlso right</returns> public static Expression<T> AndAlso<T>(this Expression<T> left, Expression<T> right) { return AndAlso(new List<Expression<T>>() { left, right }); } /// <summary> /// 使用OrElse合并表达式 /// </summary> /// <typeparam name=”T”></typeparam> /// <param name=”exprs”></param> /// <returns></returns> public static Expression<T> OrElse<T>(this IList<Expression<T>> exprs) { if (exprs.Count==0) return null; if (exprs.Count==1) return exprs[0]; var leftExpr=exprs[0]; var left=leftExpr.Body; for (int i=1; i < exprs.Count; i++) { var expr=exprs[i]; var visitor=GetReplaceExpressionVisitor(expr.Parameters, leftExpr.Parameters); var right=visitor.Visit(expr.Body); left=Expression.OrElse(left, right); } return Expression.Lambda<T>(left, leftExpr.Parameters); } /// <summary> /// 使用OrElse合并表达式 /// </summary> /// <typeparam name=”T”></typeparam> /// <param name=”left”></param> /// <param name=”right”></param> /// <returns>left OrElse right</returns> public static Expression<T> OrElse<T>(this Expression<T> left, Expression<T> right) { return OrElse(new List<Expression<T>>() { left, right }); } /// <summary> /// 构建visitor /// </summary> /// <param name=”oldParameters”></param> /// <param name=”newParameters”></param> /// <returns></returns> private static ReplaceExpressionVisitor GetReplaceExpressionVisitor(ReadOnlyCollection<ParameterExpression> oldParameters, ReadOnlyCollection<ParameterExpression> newParameters) { Dictionary<Expression, Expression> dic=new Dictionary<Expression, Expression>(); for (int i=0; i < oldParameters.Count; i++) { dic.Add(oldParameters[i],newParameters[i]); } return new ReplaceExpressionVisitor(dic); } }