扩展方法如何在后台工作?

Fre*_*ood 2 .net c# linq extension-methods

关于扩展方法机制的背后,我只是痴迷.有些问题和答案出现在我的脑海里.

MyClass.OrderBy(x=>x.a).OrderBy(x=>x.b);
Run Code Online (Sandbox Code Playgroud)

我猜测机制是第一个orderby方法工作,并由一个成员命令然后返回IEnumarable接口中的排序项然后下一个IEnumarable的Orderby方法为b paramater命令它们.但是当我看这个linq查询时我错了.

MyClass.Orderby(x=>x.a).ThenOrderBy(x=>x.b);
Run Code Online (Sandbox Code Playgroud)

这是略有不同,并告诉我,我错了.因为这不是由当时的b订购,如果我是对的,也不可能有这样的结果.这让我感到困惑......

类似的结构可以用扩展方法编写作为第一个查询,但第二个是不可能的.这证明我错了.你可以解释一下吗?

Sim*_*ens 6

其他人已经很好地解释了在编译期间如何将扩展方法转换为静态方法,所以我不打算深入研究.

我想你要问的是OrderBy和ThenBy如何在按顺序调用它们时设法产生正确的顺序,所以我将尝试回答你问题的那一部分.


扩展方法Enumerable.OrderBy返回一个IOrderedEnumerable,支持它的具体类是OrderedEnumerable,它在内部存储用于对可枚举进行排序的函数.

当您调用ThenBy时,您正在调用静态Enumerable.ThenBy方法并将OrderedEnumerable从第一次调用的输出传递给OrderBy,后者创建第二个OrderedEnumerable.第二个OrderedEnumerable将包含对第一次创建的父OrderedEnumerable的引用.

所以你所拥有的是一个OrderedEnumerable,它包含一个父OrderedEnumerable,每个都有为了排序而存储的相应函数.当您枚举它时,每个OrderedEnumerable首先委托它的父级,并且只有在父级无法分离正在排序的项目时才使用它自己的排序函数.显然,没有理由不能拥有几个OrderedEnumerables的链,并且它总是最内部的,它首先调用它的排序函数.

I drew a quick diagram to try and help explain:

link text http://i48.tinypic.com/smdf1g.png


I hope that makes sense. I hope I haven't confused the situation there, I think I've pretty much worn out the word 'enumerable'. If you need more detail you can use reflector to take a look at the what the various methods are doing under the covers.