【问题标题】:Why does this Linq method accepts parameters of type Expression为什么这个 Linq 方法接受 Expression 类型的参数
【发布时间】:2019-09-28 10:35:36
【问题描述】:

我在其他post中找到了这个方法,除了第4行之外,我几乎明白这是怎么回事:

public static IQueryable<T> OrderByMember<T>(this IQueryable<T> source, string memberPath)
{
    var expression = source.Expression;

    var parameter = Expression.Parameter(source.ElementType, "x");

    string[] paths = memberPath.Split('.');

    /*****************HERE*******************/

    var member = paths.Aggregate((Expression)parameter, Expression.PropertyOrField);

    /****************************************/




    var selector = Expression.Lambda(member, parameter);
    var orderByCall = Expression.Call(typeof(Queryable), "OrderBy",
        new Type[] { parameter.Type, member.Type },
        expression, Expression.Quote(selector));
    return source.Provider.CreateQuery<T>(orderByCall);
}

为什么IEnumerable&lt;string&gt;.Aggregate 接受ExpressionMemberExpression

Aggregate 的所有重载似乎都与此调用不匹配

https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.aggregate?view=netframework-4.6.2

由于我不知道那里发生了什么,请您解释一下吗?

【问题讨论】:

  • 那么数组实现了IQueryable?
  • 糟糕!我脑残了。 parameter 是种子,PropertyOrField 是累加器。它叫这个overload

标签: c# linq lambda expression-trees iqueryable


【解决方案1】:

为什么 IEnumerable.Aggregate 接受 ExpressionMemberExpression

传递给Aggregate 的第二个参数不是 MemberExpression!仔细看!

Expression.PropertyOrField 不是属性。这是一种方法。由于末尾没有括号,因此您没有调用它。 Expression.PropertyOrField 在这里代表一个方法组。

Expression.PropertyOrField 接受一个Expression 和一个string 并返回一个MemberExpression,因此它可以由委托类型Func&lt;Expression, string, MemberExpression&gt; 表示。第一个参数的类型是Expression,所以你实际上是在调用:

Aggregate(Expression, Func<Expression, string, MemberExpression>)

这与Aggregateoverload 的签名相匹配:

public static TAccumulate Aggregate<TSource,TAccumulate> (
    this System.Collections.Generic.IEnumerable<TSource> source, 
    TAccumulate seed, 
    Func<TAccumulate,TSource,TAccumulate> func);

TAccumulateExpressionTSourcestring

至于这条线在高层次上做了什么,好吧,我相信你现在已经弄清楚了。它转换字符串memberPath,可能看起来像这样:

w.x.y.z

放入表示该表达式的Expression 对象。

【讨论】:

    猜你喜欢
    • 2023-04-06
    • 2012-12-06
    • 1970-01-01
    • 2021-04-12
    • 2014-01-24
    • 1970-01-01
    • 2012-09-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多