为什么此Linq方法接受类型为Expression的参数

时间:2019-05-10 13:42:32

标签: c# linq lambda expression-trees iqueryable

我在其他post中找到了这种方法,除了第四行外,我几乎了解发生了什么事:

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

Aggregate的重载似乎都不符合此调用

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

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

1 个答案:

答案 0 :(得分:1)

  

为什么IEnumerable.Aggregate接受@forelse ($event->invitations as $event) <h5>{{ $event->email }}</h5> @empty <h5>Not Found</h5> @endforelse Expression

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

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

Expression.PropertyOrField接受一个Expression.PropertyOrField和一个Expression并返回一个string,因此可以用委托类型MemberExpression表示。第一个参数的类型为Func<Expression, string, MemberExpression>,因此您实际上是在调用:

Expression

这与Aggregate(Expression, Func<Expression, string, MemberExpression>) 中此overload的签名相符:

Aggregate

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

关于这条线的总体运作情况,好的,我确定您现在已经确定了。它会转换字符串string,看起来像这样:

memberPath

放入代表该表达式的w.x.y.z 对象中。

相关问题