using System; using System.Linq.Expressions; namespace VCommon.Linq.Expressions.Predicate.Internals { internal static class PredicateConcatUtility { public static Expression> Or(this Expression> expr1, Expression> expr2) { var secondBody = expr2.Body.Replace(expr2.Parameters[0], expr1.Parameters[0]); return Expression.Lambda>(Expression.OrElse(expr1.Body, secondBody), expr1.Parameters); } public static Expression> And(this Expression> expr1, Expression> expr2) { var secondBody = expr2.Body.Replace(expr2.Parameters[0], expr1.Parameters[0]); return Expression.Lambda>(Expression.AndAlso(expr1.Body, secondBody), expr1.Parameters); } public static Expression Replace(this Expression expression, Expression searchEx, Expression replaceEx) { return new ReplaceVisitor(searchEx, replaceEx).Visit(expression); } private class ReplaceVisitor : ExpressionVisitor { private readonly Expression _from, _to; public ReplaceVisitor(Expression from, Expression to) { _from = from; _to = to; } public override Expression Visit(Expression node) { return node == _from ? _to : base.Visit(node); } } } }