Last active
September 4, 2018 21:28
-
-
Save j2jensen/9374c8f4966792da8058adb476d88262 to your computer and use it in GitHub Desktop.
Create "OR"ed Expression from two expressions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Like it!