26

IQueryableシーケンスのフィルタリングに使用される式を無効にする方法を探しています。

だから、私は次のようなものを持っています:

Expression<Func<T, bool>> expression = (x => true);

ここで、降伏する式を作成し(x => false)たいので、基本的には否定したいと思いexpressionます。

私が見つけた作業方法は次のように機能します。

var negatedExpression = 
   Expression.Lambda<Func<T, bool>> (Expression.Not(expression.Body),
                                     expression.Parameters[0])));

しかし、私はもっと良い方法があるとほぼ確信しています-あなたは私を助けてくれますか?Not(expression)(おそらく、のようなもの)。

4

3 に答える 3

26

簡単な拡張方法:

public static Expression<Func<T, bool>> Not<T>(this Expression<Func<T, bool>> one)
{
    var candidateExpr = one.Parameters[0];
    var body = Expression.Not(one.Body);

    return Expression.Lambda<Func<T, bool>>(body, candidateExpr);
}

使用法:

Expression<Func<int, bool>> condition = x => x > 5;
var source = Enumerable.Range(1, 10);
var result1 = source.Where(condition.Compile());   //6,7,8,9,10
var result2 = source.Where(condition.Not().Compile());    //1,2,3,4,5
于 2010-12-11T16:06:53.790 に答える
3

将来の参考のために投稿します。

Danny Chenの答えは、より一般的にすることができます。

public static Expression<TFunc> Not<TFunc>(this Expression<TFunc> baseExpr)
{
    var param = baseExpr.Parameters;
    var body = Expression.Not(baseExpr.Body);
    var newExpr = Expression.Lambda<TFunc>(body, param);
    return newExpr;
}

このバージョンは、任意の数の入力パラメーターを持つ式を受け取ることができます。ただし、式はIEnumerable.Whereとにかく関数に渡される可能性が高いため、使いやすさは少し向上します。

于 2017-08-09T20:36:37.243 に答える
-4

これはどうですか?

Expression<Func<bool>> expr = () => true;
Expression<Func<bool>> negated = () => !expr.Compile()();
于 2010-12-11T15:56:28.867 に答える