3

質問を表現するより良い方法は考えられませんでしたが、私がやろうとしているのは、LambdaExpression が評価される前にのインスタンスを処理することによってExpression<Func<MyObject, FilterObject, bool>>、LambdaExpression の署名を から に減らすことです。Expression<Func<MyObject, bool>>FilterObject

簡単な例を次に示します。

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;
    }
}

したがって、このオーバーロードでAddFilter型のオブジェクトを作成FilterObjectし、次の行に沿って LambdaExpression に埋め込む必要があります。

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

これを行うためのより良い方法があるかもしれないので、このアプローチを完全に回避する提案を受け入れます.

4

2 に答える 2

0

を呼び出すよりも優れた方法はInvokeExpressionVisitor. これを簡単にするために、いくつかの単純な拡張メソッドを定義できます。この場合、式の最初のパラメーターを適用できます (署名を変更するか、署名を調整して中間パラメーターを適用する必要があります)。

使用法:

      var applied = expr.Apply(constValueForFirstParameter);

静的クラスでは、次の拡張メソッドを定義します。

public static Expression<Func<U, V, bool>> Apply<T, U, V>(this Expression<Func<T, U, V, bool>> input, T value)
{
    var swap = new ExpressionSubstitute(input.Parameters[0], Expression.Constant(value));
    var lambda = Expression.Lambda<Func<U, V, bool>>(swap.Visit(input.Body), input.Parameters[1], input.Parameters[2]);
    return lambda;
}

public static Expression<Func<U, bool>> Apply<T, U>(this Expression<Func<T, U, bool>> input, T value)
{
    var swap = new ExpressionSubstitute(input.Parameters[0], Expression.Constant(value));
    var lambda = Expression.Lambda<Func<U, bool>>(swap.Visit(input.Body), input.Parameters[1]);
    return lambda;
}

class ExpressionSubstitute : System.Linq.Expressions.ExpressionVisitor
{
    private readonly Expression from, to;
    public ExpressionSubstitute(Expression from, Expression to)
    {
        this.from = from;
        this.to = to;
    }

    public override Expression Visit(Expression node)
    {
        if (node == from) return to;
        return base.Visit(node);
    }
}
于 2015-11-10T02:55:55.123 に答える