views:

133

answers:

3

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 ?

+1  A: 

extension methods are just syntactic sugar and they are replaced by actual static method calls in compiled IL.

consider this extension method that checks if a string is valid email.

    public static bool IsEmail(this string email)
    {
        if (email != null)
        {
            return Regex.IsMatch(email, "EmailPattern");
        }

        return false;
    }

in C# I'll call this extension method as below.

string str = "[email protected]";
bool isValidEmail = str.IsEmail();

After compilation the call to str.IsEmail() is replaced by IsEmail(str);

In case of, MyClass.OrderBy(x=>x.a).OrderBy(x=>x.b); each extension method returns the type of instance on which the subsequent extension method is defined. This is called chaining of method calls or more appropriately a technique called fluent-interfacing

this. __curious_geek
Yes , i already know extension methods but this is not answer of my question yet.
Freshblood
A: 

You are right, the extension methods are executed in the same order as they appear, passing its result to the next extension method. I don't know why your ordering doesn't work as you expect.

Assuming extension methods A.A(this X) and B.B(this X):

x.A().B()

is equivalent to

B.B(A.A(x))
Stefan Steinegger
But strange things how thenOrderBy can sort them ??? this is big question for me.How can it Sort it by b field without crash Array which is already sorted by a ? Can u answer this.
Freshblood
Sorting an IEnumerable doesn't change the array behind. It creates a new IEnumerable which returns the items in sorted order.
Stefan Steinegger
+5  A: 

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

Simon P Stevens
Perfect answer.You understand my question very well.As u can see many programmers didn't think what i was thinking.OrderedEnumerable contains sorting function inside of it then next method can check it. This explain my question.Thank you very much
Freshblood