Search code examples
c#expression-trees

Reduce a LambdaExpression Signature


I couldn't think of a better way to word the question, but what I'm trying to do is reduce the signature of a LambdaExpression from Expression<Func<MyObject, FilterObject, bool>> to Expression<Func<MyObject, bool>> by handling the instance of the FilterObject before the LambdaExpression is evaluated.

Here's a quick example:

AddFilter("Filter Name", FilterTypes.All,
    (x, y) => GetConjunctionResult(
        x.PersonA.IsSomething, x.PersonB.IsSomething, y.ConjunctionType));

private static bool GetConjunctionResult(bool personA, bool personB,
    ConjunctionType conjunctionType)
{
    switch (conjunctionType)
    {
        case ConjunctionType.Both:
            return personA && personB:
        case ConjunctionType.Either:
            return personA && personB;
        case ConjunctionType.PersonA:
            return personA;
        case ConjunctionType.PersonB:
            return personB;
        case ConjunctionType.Neither:
            return !personA && !personB;
    }
}

So I want this overload of AddFilter to create an object of type FilterObject and embed it into a LambdaExpression along the lines of:

var filter = new FilterObject();
// create Expression<Func<MyObject, bool>> lambda = x => GetConjunctionResult(
//     x.PersonA.IsSomething, x.PersonB.IsSomething, filter.ConjunctionType));

Now there might be a better way to do this, so I'm open to any suggestions that eschew this approach altogether.


Solution

  • Given

    var filter = new FilterObject()
    

    it should be:

    Expression<Func<MyObject, bool>> exp2 = 
                 Expression.Lambda<Func<MyObject, bool>>(
                            Expression.Invoke(myExp, 
                                              myExp.Parameters[0], 
                                              Expression.Constant(filter)),
                            myExp.Parameters[0]);
    

    Expression.Invoke will call the other expression and pass as the first parameter the first parameter of the new expression, and as the second parameter an Expression.Constant with your filter.

    Are you trying to use Currying with Expression trees?