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

标签 c# linq lambda expression-trees iqueryable

我在其他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接受 Expression和一个 MemberExpression

Aggregate 的重载似乎都不匹配这个调用

https://learn.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并返回 MemberExpression , 所以它可以用委托(delegate)类型 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);

TAccumulateExpressionTSourcestring .

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

w.x.y.z

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

关于c# - 为什么这个 Linq 方法接受表达式类型的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56078927/

相关文章:

c# - 缺少 System.Windows.Shell 引用

c# - 表达式转换错误 - 类型之间没有定义强制运算符

c# - 表达式树 : Filtered count on navigation property

entity-framework - 按另一个列表/数组过滤 Linq 子集合

lambda - 避免由于冗余转换而导致 lambda 表达式中出现代码分析 CA1800 错误

lambda - 在方案中使用多个 lambda 是什么意思?

c# - 用子项序列化对象 c#

c# - 如何为用户的每个新值将列表项格式化为不同的表行

java - 从没有空指针异常的 Map 的 Map 的 Map 中获取值

c# - (读取)文件 I/O 抖动