Search code examples
c#.netlinqextension-methods

How extension methods work in background?


I am just cuirous about behind of extension method mechanism.Some questions and answer appear in my mind.

MyClass.OrderBy(x=>x.a).OrderBy(x=>x.b);

I was guessing that mechanism was first orderby method works and order them by a member then returns sorted items in IEnumarable interface then next Orderby method of IEnumarable Order them for b paramater.But i am wrong when i look at this linq query.

MyClass.Orderby(x=>x.a).ThenOrderBy(x=>x.b);

this is slightly different and tells me that i am wrong.Because this is not ordering by a then b and not possible to have such result if i was right.This get me confuse enough...

Similiar structure is possible to write withot extension methods as first query but second is not possible.This prove i am wrong . Can u explain it ?


Solution

  • Others have explained very well how extension methods are converted into static methods during compilation so I'm not going to get into that.

    I think what you are asking though is how OrderBy and ThenBy manage to produce the correct ordering when they are called in sequence, so I am going to try and answer that part of your question.


    The extension method Enumerable.OrderBy returns an IOrderedEnumerable, the concrete class that backs this is an OrderedEnumerable, which internally stores the function that is used to sort the enumerable.

    When you call ThenBy, you are calling the static Enumerable.ThenBy method and passing the OrderedEnumerable from the output of the first call to OrderBy which creates a second OrderedEnumerable. This second OrderedEnumerable will contain a reference to the parent OrderedEnumerable that was created the first time.

    So what you have is a OrderedEnumerable that contains a parent OrderedEnumerable, each with the appropriate functions stored for ordering. When you enumerate over it, each OrderedEnumerable first delegates to it's parent, and only uses it's own sorting function when the parent is unable to separate the items being sorted. Obviously, there is no reason why you can't have a chain of several OrderedEnumerables, and it will always be the inner most that gets to call it's sorting function first.

    I drew a quick diagram to try and help explain:

    link text


    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 ILSpy to take a look at the what the various methods are doing under the covers.