Skip to content

Instantly share code, notes, and snippets.

@CraftyFella
Created November 22, 2013 10:16
Show Gist options
  • Save CraftyFella/7597741 to your computer and use it in GitHub Desktop.
Save CraftyFella/7597741 to your computer and use it in GitHub Desktop.
Anding two expressions together
using System;
using System.Collections.ObjectModel;
using System.Linq.Expressions;
namespace CTM.Home.MaiyaReports.Processors
{
void Main()
{
Expression<Func<ArrayList, bool>> @default = r => r.Count > 0 && r.Count < 2;
Expression<Func<ArrayList, bool>> extra = ar => ar.Capacity > 0;
@default.AndAlso(extra).Dump();
}
class ParameterVisitor : ExpressionVisitor
{
private readonly ReadOnlyCollection<ParameterExpression> from, to;
public ParameterVisitor(
ReadOnlyCollection<ParameterExpression> from,
ReadOnlyCollection<ParameterExpression> to)
{
if (from == null) throw new ArgumentNullException("from");
if (to == null) throw new ArgumentNullException("to");
if (from.Count != to.Count) throw new InvalidOperationException(
"Parameter lengths must match");
this.from = from;
this.to = to;
}
protected override Expression VisitParameter(ParameterExpression node)
{
for (int i = 0; i < from.Count; i++)
{
if (node == from[i]) return to[i];
}
return node;
}
}
public static class ExpressionExtensions
{
public static Expression<Func<T, bool>> AndAlso<T>(this Expression<Func<T, bool>> x, Expression<Func<T, bool>> y)
{
var newY = new ParameterVisitor(y.Parameters, x.Parameters)
.VisitAndConvert(y.Body, "AndAlso");
return Expression.Lambda<Func<T, bool>>(
Expression.AndAlso(x.Body, newY),
x.Parameters);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment