【问题标题】:Understanding Expression.Invoke() Method了解 Expression.Invoke() 方法
【发布时间】:2013-11-08 23:25:00
【问题描述】:

我一直在理解 Joseph Albahari 写的 PredicateBuilder 扩展方法,我看到了这个 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);
}

尽管他解释了一点:

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

MSDN 告诉我:

创建一个应用委托或 lambda 的 InvocationExpression 表达式到参数表达式列表。

这对我来说有点道理。因此,如果我使用这样的表达式,基本上我不必传递任何参数。

但由于某种原因,我不能完全理解它。也许是我累了。

问题:

  1. 在什么情况下使用InvocationExpression是有意义的。
  2. 谁能解释一下Or&lt;T&gt; 方法(或AndElse&lt;T&gt;)方法如何更好地工作?

更新:

当我下班回家的时候,我在想InvocationExpression,它在我的脑海里暗示了这样一个:

当我们调用一个方法时,我们简单地说CallMe(phoneNumber, time);,这称为方法调用。那么,InvocationExpression 应该是表达CallMe(phoneNumber, time); 的表达式。它类似于LambdaExpression,它表示一个lambda,例如t =&gt; t + 2。所以基本上它是一个应用于参数(不是参数)的方法调用。因此,作为调用,它不再需要参数,但可能会返回一些东西,因为参数已经应用于它的参数。

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

【问题讨论】:

    标签: c# expression-trees


    【解决方案1】:

    想象一下,您使用的不是表达式,而是代表。然后你可以这样写Or

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

    您创建一个调用两个委托的新委托,并使用|| 组合。当您重写它以使用表达式时,调用委托会变成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);
    }
    

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

    【讨论】:

      猜你喜欢
      • 2016-07-06
      • 2014-07-20
      • 2015-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-01
      • 1970-01-01
      相关资源
      最近更新 更多