LambdaCombiner.cs 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. using System.Linq.Expressions;
  2. namespace VberZero.Tools.Lambda;
  3. public static class LambdaCombiner
  4. {
  5. public static Expression<Func<T, bool>> Combine<T>(Expression<Func<T, bool>> expression1, Expression<Func<T, bool>> expression2)
  6. {
  7. if (expression1 == null && expression2 == null)
  8. {
  9. return null;
  10. }
  11. if (expression1 == null)
  12. {
  13. return expression2;
  14. }
  15. if (expression2 == null)
  16. {
  17. return expression1;
  18. }
  19. var parameter = Expression.Parameter(typeof(T));
  20. var leftVisitor = new ReplaceExpressionVisitor(expression1.Parameters[0], parameter);
  21. var left = leftVisitor.Visit(expression1.Body);
  22. var rightVisitor = new ReplaceExpressionVisitor(expression2.Parameters[0], parameter);
  23. var right = rightVisitor.Visit(expression2.Body);
  24. return Expression.Lambda<Func<T, bool>>(Expression.AndAlso(left, right), parameter);
  25. }
  26. private class ReplaceExpressionVisitor : ExpressionVisitor
  27. {
  28. private readonly Expression _oldValue;
  29. private readonly Expression _newValue;
  30. public ReplaceExpressionVisitor(Expression oldValue, Expression newValue)
  31. {
  32. _oldValue = oldValue;
  33. _newValue = newValue;
  34. }
  35. public override Expression Visit(Expression node)
  36. {
  37. if (node == _oldValue)
  38. {
  39. return _newValue;
  40. }
  41. return base.Visit(node);
  42. }
  43. }
  44. }