为什么这个 Linq 方法接受表达式类型的参数

Why does this Linq method accepts parameters of type Expression

我在其他 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<string>.Aggregate 接受 ExpressionMemberExpression

None 的聚合重载似乎匹配此调用

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

因为我不知道那里发生了什么,你能解释一下吗?

Why does IEnumerable.Aggregate accepts an Expression and a MemberExpression?

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

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

Expression.PropertyOrField接受一个Expression和一个string和returns一个MemberExpression,所以它可以用委托类型[=23=来表示].第一个参数是 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.

至于这条线在 high-level 上的作用,嗯,我相信您现在已经明白了。它转换字符串 memberPath,它可能看起来像这样:

w.x.y.z

到表示该表达式的 Expression 对象中。