ExpressionExtensions.cs 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. namespace Jellyfin.Server.Implementations.Extensions;
  6. /// <summary>
  7. /// Provides <see cref="Expression"/> extension methods.
  8. /// </summary>
  9. public static class ExpressionExtensions
  10. {
  11. /// <summary>
  12. /// Combines two predicates into a single predicate using a logical OR operation.
  13. /// </summary>
  14. /// <typeparam name="T">The predicate parameter type.</typeparam>
  15. /// <param name="firstPredicate">The first predicate expression to combine.</param>
  16. /// <param name="secondPredicate">The second predicate expression to combine.</param>
  17. /// <returns>A new expression representing the OR combination of the input predicates.</returns>
  18. public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> firstPredicate, Expression<Func<T, bool>> secondPredicate)
  19. {
  20. ArgumentNullException.ThrowIfNull(firstPredicate);
  21. ArgumentNullException.ThrowIfNull(secondPredicate);
  22. var invokedExpression = Expression.Invoke(secondPredicate, firstPredicate.Parameters);
  23. return Expression.Lambda<Func<T, bool>>(Expression.OrElse(firstPredicate.Body, invokedExpression), firstPredicate.Parameters);
  24. }
  25. /// <summary>
  26. /// Combines multiple predicates into a single predicate using a logical OR operation.
  27. /// </summary>
  28. /// <typeparam name="T">The predicate parameter type.</typeparam>
  29. /// <param name="predicates">A collection of predicate expressions to combine.</param>
  30. /// <returns>A new expression representing the OR combination of all input predicates.</returns>
  31. public static Expression<Func<T, bool>> Or<T>(this IEnumerable<Expression<Func<T, bool>>> predicates)
  32. {
  33. ArgumentNullException.ThrowIfNull(predicates);
  34. return predicates.Aggregate((aggregatePredicate, nextPredicate) => aggregatePredicate.Or(nextPredicate));
  35. }
  36. /// <summary>
  37. /// Combines two predicates into a single predicate using a logical AND operation.
  38. /// </summary>
  39. /// <typeparam name="T">The predicate parameter type.</typeparam>
  40. /// <param name="firstPredicate">The first predicate expression to combine.</param>
  41. /// <param name="secondPredicate">The second predicate expression to combine.</param>
  42. /// <returns>A new expression representing the AND combination of the input predicates.</returns>
  43. public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> firstPredicate, Expression<Func<T, bool>> secondPredicate)
  44. {
  45. ArgumentNullException.ThrowIfNull(firstPredicate);
  46. ArgumentNullException.ThrowIfNull(secondPredicate);
  47. var invokedExpression = Expression.Invoke(secondPredicate, firstPredicate.Parameters);
  48. return Expression.Lambda<Func<T, bool>>(Expression.AndAlso(firstPredicate.Body, invokedExpression), firstPredicate.Parameters);
  49. }
  50. /// <summary>
  51. /// Combines multiple predicates into a single predicate using a logical AND operation.
  52. /// </summary>
  53. /// <typeparam name="T">The predicate parameter type.</typeparam>
  54. /// <param name="predicates">A collection of predicate expressions to combine.</param>
  55. /// <returns>A new expression representing the AND combination of all input predicates.</returns>
  56. public static Expression<Func<T, bool>> And<T>(this IEnumerable<Expression<Func<T, bool>>> predicates)
  57. {
  58. ArgumentNullException.ThrowIfNull(predicates);
  59. return predicates.Aggregate((aggregatePredicate, nextPredicate) => aggregatePredicate.And(nextPredicate));
  60. }
  61. }