我只是对扩展方法机制的背后很好奇。一些问题和答案出现在我的脑海中。
MyClass.OrderBy(x=>x.a).OrderBy(x=>x.b);
我猜想机制是第一个orderby方法起作用并且由成员对其进行排序,然后在IEnumarable接口中返回已排序的项目,然后在IEnumarable接口的下一个Orderby方法中返回b参数。但是当我查看此linq查询时,我错了。
MyClass.Orderby(x=>x.a).ThenOrderBy(x=>x.b);
这有点不同,告诉我我错了。因为这不是按a然后b排序,如果我是对的就不可能有这样的结果。这让我很困惑...
类似的结构可以编写withot扩展方法作为第一个查询,但第二个不可能。这证明我是错误的。你能解释一下吗?
最佳答案
Others have explained很好,在编译过程中如何将扩展方法转换为静态方法,因此我不再赘述。
我想您想问的是,当OrderBy和ThenBy依次被调用时,它们是如何设法产生正确的排序的,所以我将尝试回答问题的这一部分。
扩展方法Enumerable.OrderBy返回IOrderedEnumerable,支持它的具体类是OrderedEnumerable,该类在内部存储用于对可枚举进行排序的函数。
当您调用ThenBy时,您正在调用静态Enumerable.ThenBy方法并将OrderedEnumerable从第一次调用的输出传递给OrderBy,后者将创建第二个OrderedEnumerable。第二个OrderedEnumerable将包含对第一次创建的父OrderedEnumerable的引用。
因此,您所拥有的是一个OrderedEnumerable,其中包含父OrderedEnumerable,每个父级都存储有用于排序的适当函数。枚举时,每个OrderedEnumerable首先将其委托给它的父级,并且仅在父级无法分离要排序的项目时才使用它自己的排序功能。显然,没有理由不能拥有几个OrderedEnumerables的链,并且它始终是最内在的,因此必须首先调用其排序功能。
我画了一个简单的图表来尝试帮助解释:
我希望这是有道理的。我希望我不要混淆那里的情况,我认为我已经很累了“可数”这个词。如果需要更多详细信息,可以使用reflector来了解各种方法的内容。