了解Expression.Invoke()方法

Tar*_*rik 23 c# expression-trees

我一直在理解PredicateBuilderJoseph Albahari编写的扩展方法,我看到了这一点Expression.Invoke,说实话,我无法理解它的原因在以下方法中:

public static Expression<Func<T, bool>> Or<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.OrElse (expr1.Body, invokedExpr), expr1.Parameters);
}
Run Code Online (Sandbox Code Playgroud)

即使他解释了一下:

有趣的工作发生在And和Or方法中.我们首先使用第一个表达式的参数调用第二个表达式.Invoke表达式使用给定表达式作为参数调用另一个lambda表达式.我们可以从第一个表达式的主体和第二个表达式的调用版本创建条件表达式.最后一步是将它包装在一个新的lambda表达式中.

MSDN告诉我:

创建一个InvocationExpression,将委托或lambda表达式应用于参数表达式列表.

这对我来说很有意义.所以基本上我不必传入任何参数,如果我使用这样的表达式.

但由于某种原因,我无法理解它.也许我累了什么的.

问题:

  1. 何时以及在何种情况下使用是有意义的InvocationExpression.
  2. 任何人都可以解释Or<T>方法(或AndElse<T>)方法如何更好地工作?

更新:

我在考虑InvocationExpression当我从工作到家时,它在我心中暗示如下:

当我们调用一个方法时,我们简单地说CallMe(phoneNumber, time);,这称为方法调用.然后,InvocationExpression应该是一个表达的表达CallMe(phoneNumber, time);.它类似于LambdaExpression表达lambda等t => t + 2.所以基本上它是一个应用于参数(而不是参数)的方法调用.因此,作为调用,不再需要参数,但可能会返回一些内容,因为参数已经应用于其参数.

有关我正在讨论的代码的更多信息,请访问http://www.albahari.com/nutshell/predicatebuilder.aspx

svi*_*ick 37

想象一下,你没有使用表达式,而是与代表一起工作.然后你可以Or像这样写:

public static Func<T, bool> Or<T>(this Func<T, bool> expr1, Func<T, bool> expr2)
{
    return x => expr1(x) || expr2(x);
}
Run Code Online (Sandbox Code Playgroud)

您创建一个新的委托,调用两个委托,使用组合||.当您重写它以使用表达式时,调用委托将变为Expression.Invoke():

public static Expression<Func<T, bool>> Or<T>(
    this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
{
    var parameter = Expression.Parameter(typeof(T), "x");
    var invokedExpr1 = Expression.Invoke(expr1, parameter);
    var invokedExpr2 = Expression.Invoke(expr2, parameter);

    return Expression.Lambda<Func<T, bool>>(
        Expression.OrElse(invokedExpr1, invokedExpr2), parameter);
}
Run Code Online (Sandbox Code Playgroud)

实际上Or不是这样编写的原因(最有可能)是优化:您不必调用这两个表达式,您可以重用其中一个表达式的主体和参数.(但是你不能重复使用它们,因为它们有不同的参数.)