Skip to content

Instantly share code, notes, and snippets.

@j2jensen
Last active September 4, 2018 21:28
Show Gist options
  • Save j2jensen/9374c8f4966792da8058adb476d88262 to your computer and use it in GitHub Desktop.
Save j2jensen/9374c8f4966792da8058adb476d88262 to your computer and use it in GitHub Desktop.
Create "OR"ed Expression from two expressions
public class ExpressionReplacer : ExpressionVisitor
{
private readonly Func<Expression, Expression> replacer;
public ExpressionReplacer(Func<Expression, Expression> replacer)
{
this.replacer = replacer;
}
public override Expression Visit(Expression node)
{
return base.Visit(replacer(node));
}
}
public static class ExpressionUtilities
{
public static T ReplaceParameter<T>(T expr, ParameterExpression toReplace, ParameterExpression replacement)
where T : Expression
{
var replacer = new ExpressionReplacer(e => e == toReplace ? replacement : e);
return (T)replacer.Visit(expr);
}
public static Expression<Func<T, TReturn>> Join<T, TReturn>(Func<Expression, Expression, BinaryExpression> joiner, IReadOnlyCollection<Expression<Func<T, TReturn>>> expressions)
{
if (!expressions.Any())
{
throw new ArgumentException("No expressions were provided");
}
var firstExpression = expressions.First();
var otherExpressions = expressions.Skip(1);
var firstParameter = firstExpression.Parameters.Single();
var otherExpressionsWithParameterReplaced = otherExpressions.Select(e => ReplaceParameter(e.Body, e.Parameters.Single(), firstParameter));
var bodies = new[] { firstExpression.Body }.Concat(otherExpressionsWithParameterReplaced);
var joinedBodies = bodies.Aggregate(joiner);
return Expression.Lambda<Func<T, TReturn>>(joinedBodies, firstParameter);
}
}
public class Program
{
void Main()
{
Expression<Func<int, bool>> expr = i => i > 5;
Expression<Func<int, bool>> expr2 = j => j < 3;
var joined = ExpressionUtilities.Join(Expression.Or, new[] { expr, expr2});
Console.WriteLine(joined.ToString());
}
}
@imranq2
Copy link

imranq2 commented Sep 4, 2018

Like it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment