【问题标题】:C# negate an expressionC# 否定一个表达式
【发布时间】:2011-05-23 23:28:21
【问题描述】:

我正在寻找一种方法来否定用于过滤IQueryable 序列的表达式。

所以,我有类似的东西:

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

现在我希望创建将导致产生 (x =&gt; false) 的表达式 - 所以我基本上想否定 expression

我发现自己的工作方法是这样的:

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

但我几乎可以肯定有更好的方法 - 你能帮我吗?(可能类似于 Not(expression))。

【问题讨论】:

    标签: c# expression negate


    【解决方案1】:

    一种简单的扩展方法:

    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
    

    【讨论】:

    • 嗯,我确实知道如何将我的否定语句包装成“非”方法,但我实际上是在寻找一种简单的方法来实际执行否定 (它看起来对我来说,打电话给Expression.Lambda.Blablabla 太过分了)。
    • 表达式树是不可变的,所以你必须创建一个新的 lambda。
    【解决方案2】:

    张贴以供将来参考。

    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 这样的函数。

    【讨论】:

      【解决方案3】:

      这个呢?

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

      【讨论】:

      • 您刚刚将输入表达式转换为不透明的方法调用。这根本没有帮助,因为使用表达式的目的是提供的查询可以理解它。
      猜你喜欢
      • 2014-04-17
      • 1970-01-01
      • 2013-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-04
      • 2017-11-30
      相关资源
      最近更新 更多