gpt4 book ai didi

c# - PredicateBuilder 是如何工作的

转载 作者:IT王子 更新时间:2023-10-29 04:12:43 26 4
gpt4 key购买 nike

C# in a Nutshell 有一个名为 PredicateBuilder 的免费类,它可以逐个构建 LINQ 谓词 here .这是向谓词添加新表达式的方法的摘录。有人可以解释一下吗? (我已经看到了 this question ,我不想要像那里那样的一般性答案。我正在寻找有关 Expression.Invoke 和 Expression.Lambda 如何构建新表达式的具体解释)。

public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.AndAlso (expr1.Body, invokedExpr), expr1.Parameters);
}

最佳答案

假设您有:

Expression<Func<Person, bool>> isAdult = p1 => p1.Age >= 18;

// I've given the parameter a different name to allow you to differentiate.
Expression<Func<Person, bool>> isMale = p2 => p2.Gender == "Male";

然后将它们与PredicateBuilder结合起来

var isAdultMale = isAdult.And(isMale);

PredicateBuilder 生成的表达式如下所示:

// Invoke has no direct equivalent in C# lambda expressions.
p1 => p1.Age >= 18 && Invoke(p2 => p2.Gender == "Male", p1)

如你所见:

  1. 生成的 lambda 重用第一个表达式的参数。
  2. 具有通过传递第一个表达式的参数来替换第二个表达式的参数来调用第二个表达式的主体。结果 InvocationExpression有点像方法调用的表达式等价物(通过传入参数参数来调用例程)。
  3. And 将第一个表达式的主体和此 InvocationExpression 一起生成结果 lambda 的主体。

这个想法是 LINQ 提供程序应该能够理解此操作的语义并采取明智的行动(例如,生成类似 WHERE age >= 18 AND gender = 'Male' 的 SQL ).

尽管如此,提供商通常会遇到 InvocationExpression 的问题,因为处理“表达式内的嵌套表达式调用”会很复杂。

为了解决这个问题,LINQKit 还提供了 Expand 帮助程序。这实质上通过用嵌套表达式的 body 替换调用来巧妙地“内联”调用调用,适本地替换嵌套表达式参数的使用(在这种情况下,替换 p2使用 p1)。这应该产生如下内容:

p1 => p1.Age >= 18 && p1.Gender == "Male"

请注意,如果您自己在 lambda 中完成这些谓词,您将如何手动组合这些谓词。但是有了 LINQKit,您可以从独立来源获取这些谓词并轻松组合它们:

  1. 无需“手工”编写表达式代码。
  2. 可选地,以对生成的 lambda 的消费者透明的方式。

关于c# - PredicateBuilder 是如何工作的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11490893/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com