开发者

C# negate an expression

开发者 https://www.devze.com 2023-01-30 06:32 出处:网络
I\'m seeking for a way to negate an expression used to filter IQueryable sequences. So, I\'ve got something like:

I'm seeking for a way to negate an expression used to filter IQueryable sequences.

So, I've got something like:

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

Now I wish to create the expression which would result in yielding (x => false) - so I basically want to negate the expression.

The working method I've found myself works like this:

var negatedExpression = 
   Expression.Lambd开发者_JAVA百科a<Func<T, bool>> (Expression.Not(expression.Body),
                                     expression.Parameters[0])));

But I'm almost sure there is a better way - could you help me? (something like Not(expression), probably).


An easy extension method:

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

Usage:

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


Posting for future reference.

Danny Chen's answer can be made more generic:

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

This version can receive an Expression with any number of input parameters. It only adds a little useability, however, since the Expression would most likely be passed to a function like IEnumerable.Where anyway.


What about this?

Expression<Func<bool>> expr = () => true;
Expression<Func<bool>> negated = () => !expr.Compile()();
0

精彩评论

暂无评论...
验证码 换一张
取 消