【问题标题】:How do I compose existing Linq Expressions如何编写现有的 Linq 表达式
【发布时间】:2010-09-08 09:22:33
【问题描述】:

我想组合两个 Linq 表达式的结果。它们以形式存在

Expression<Func<T, bool>>

所以我想要组合的两个本质上是一个参数(T 类型)的委托,它们都返回一个布尔值。我想要组成的结果将是布尔值的逻辑评估。我可能会将其实现为扩展方法,因此我的语法类似于:

Expression<Func<User, bool>> expression1 = t => t.Name == "steve";
Expression<Func<User, bool>> expression2 = t => t.Age == 28;
Expression<Func<User, bool>> composedExpression = expression1.And(expression2);

稍后在我的代码中,我想评估组合表达式

var user = new User();
bool evaluated = composedExpression.Compile().Invoke(user);

我已经提出了一些不同的想法,但我担心它比我希望的要复杂。这是怎么做到的?

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    这是一个例子:

    var user1 = new User {Name = "steve", Age = 28};
    var user2 = new User {Name = "foobar", Age = 28};
    
    Expression<Func<User, bool>> expression1 = t => t.Name == "steve";
    Expression<Func<User, bool>> expression2 = t => t.Age == 28;
    
    var invokedExpression = Expression.Invoke(expression2, expression1.Parameters.Cast<Expression>());
    
    var result = Expression.Lambda<Func<User, bool>>(Expression.And(expression1.Body, invokedExpression), expression1.Parameters);
    
    Console.WriteLine(result.Compile().Invoke(user1)); // true
    Console.WriteLine(result.Compile().Invoke(user2)); // false
    

    您可以通过扩展方法重用此代码:

    class User
    {
      public string Name { get; set; }
      public int Age { get; set; }
    }
    
    public static class PredicateExtensions
    {
      public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expression1,Expression<Func<T, bool>> expression2)
      {
        InvocationExpression invokedExpression = Expression.Invoke(expression2, expression1.Parameters.Cast<Expression>());
    
        return Expression.Lambda<Func<T, bool>>(Expression.And(expression1.Body, invokedExpression), expression1.Parameters);
      }
    }
    
    class Program
    {
      static void Main(string[] args)
      {
        var user1 = new User {Name = "steve", Age = 28};
        var user2 = new User {Name = "foobar", Age = 28};
    
        Expression<Func<User, bool>> expression1 = t => t.Name == "steve";
        Expression<Func<User, bool>> expression2 = t => t.Age == 28;
    
        var result = expression1.And(expression2);
    
        Console.WriteLine(result.Compile().Invoke(user1));
        Console.WriteLine(result.Compile().Invoke(user2));
      }
    }
    

    【讨论】:

    • 如何链接它们? somePredicate.And(somepredicate2).And(predicate3) 不会在 ) 附近出现错误语法错误。 (我想没有正确创建表达式)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多