Проблема в том, что параметр (foo
) не одинаков для BarMatches
и BazMatches
.Поэтому вам необходимо унифицировать параметры, чтобы выражения Or-ed использовали одно и то же.Это можно сделать с помощью заменителя выражения (украденного у этого ответа ):
static TExpr ReplaceExpressions<TExpr>(TExpr expression,
Expression orig,
Expression replacement)
where TExpr : Expression
{
var replacer = new ExpressionReplacer(orig, replacement);
return replacer.VisitAndConvert(expression, "ReplaceExpressions");
}
private class ExpressionReplacer : ExpressionVisitor
{
private readonly Expression From;
private readonly Expression To;
public ExpressionReplacer(Expression from, Expression to) {
From = from;
To = to;
}
public override Expression Visit(Expression node) {
if (node == From) {
return To;
}
return base.Visit(node);
}
}
Этот класс заменит все экземпляры одного выражения другим.Теперь мы можем использовать это для создания унифицированного выражения:
static Expression<Func<T, bool>> Or<T>(Expression<Func<T, bool>> a, Expression<Func<T, bool>> b) {
// We know Parameters is exactly of length 1.
// If you had multiple parameters you would need to invoke this for each parameter
var replaced = ReplaceExpressions(a.Body, a.Parameters[0], b.Parameters[0]);
return Expression.Lambda<Func<T, bool>>(Expression.OrElse(replaced, b.Body), b.Parameters);
}
Хотя этот код будет делать то, что вы хотите, я предлагаю использовать библиотеку, которая делает это и многое другое: LinqKIT