PredicateConcater.cs 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. using System;
  2. using System.Linq.Expressions;
  3. namespace VCommon.Linq.Expressions.Predicate.Internals
  4. {
  5. internal static class PredicateConcater
  6. {
  7. public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
  8. {
  9. var secondBody = expr2.Body.Replace(expr2.Parameters[0], expr1.Parameters[0]);
  10. return Expression.Lambda<Func<T, bool>>(Expression.OrElse(expr1.Body, secondBody), expr1.Parameters);
  11. }
  12. public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
  13. {
  14. var secondBody = expr2.Body.Replace(expr2.Parameters[0], expr1.Parameters[0]);
  15. return Expression.Lambda<Func<T, bool>>(Expression.AndAlso(expr1.Body, secondBody), expr1.Parameters);
  16. }
  17. public static Expression Replace(this Expression expression, Expression searchEx, Expression replaceEx)
  18. {
  19. return new ReplaceVisitor(searchEx, replaceEx).Visit(expression);
  20. }
  21. private class ReplaceVisitor : ExpressionVisitor
  22. {
  23. private readonly Expression _from, _to;
  24. public ReplaceVisitor(Expression from, Expression to)
  25. {
  26. _from = from;
  27. _to = to;
  28. }
  29. public override Expression Visit(Expression node)
  30. {
  31. return node == _from ? _to : base.Visit(node);
  32. }
  33. }
  34. }
  35. }