Pergunta

If I have a specification defined as an Expression as below:

public Expression<Func<Foo, bool>> IsSuperhuman = 
  x => x.CanFly && x.HasXRayVision;

And I want to define another specification 'IsSuperheroine' with the logic 'is superhuman and is female', how can I reuse the existing specification within the new one?

Foi útil?

Solução

Have you checked out predicate builder in LinqKit? It builds up expressions by letting you and and or expressions together.

Outras dicas

Here's a way to do it :

Expression<Func<Foo, bool>> IsSuperhuman = x => x.CanFly && x.HasXRayVision;

Expression<Func<Foo, bool>> IsSuperheroine = AndAlso(IsSuperhuman, x => x.IsFemale);

...

public static Expression<Func<T, TResult>> AndAlso<T, TResult>(Expression<Func<T, TResult>> expr1, Expression<Func<T, TResult>> expr2)
{
    var arg = Expression.Parameter(typeof(T), expr1.Parameters[0].Name);
    var andExpr = Expression.AndAlso(
        ReplaceParameter(expr1.Body, expr1.Parameters[0], arg),
        ReplaceParameter(expr2.Body, expr2.Parameters[0], arg));
    return Expression.Lambda<Func<T, TResult>>(andExpr, arg);
}

public static Expression ReplaceParameter(Expression expr, ParameterExpression oldParam, ParameterExpression newParam)
{
    return new ReplaceParameterVisitor(oldParam, newParam).Visit(expr);
}

internal class ReplaceParameterVisitor : ExpressionVisitor
{
    private ParameterExpression _oldParam;
    private ParameterExpression _newParam;

    public ReplaceParameterVisitor(ParameterExpression oldParam, ParameterExpression newParam)
    {
        _oldParam = oldParam;
        _newParam = newParam;
    }

    protected override Expression VisitParameter(ParameterExpression node)
    {
        if (node == _oldParam)
            return _newParam;
        return node;
    }
}

It is probably not the simplest way to do it, but it works...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top