Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How many times it is ordered a IENumerable?

Tags:

c#

ienumerable

I know that when I iterate a IEnumerable, I iterate the source collection, so if I modified the source collection in the next iteration of the IEnumerable it has in count the modificaction.

So I am wondering how it affects that when I have a ordered IEnumerable.

For example, if I have this:

List<MyType> myNoOrderedList //add my items

IEnumerable<MyType> myOrderedIEnumerable = myNoOrderedList
  .OrderBy(x => x.Property);

foreach(MyType in myOrderedIEnumerable)
{
    //Do something
}

Supose that I have 3 elements in the list, in each iteration on IEnumerable, the list is ordered or only the list is ordered once?

What happen if in "Do something" I add or remove an item? The IEnumerable has initial ordered items or has to order again to has account the modification of the list?

like image 601
Álvaro García Avatar asked Mar 09 '23 14:03

Álvaro García


1 Answers

Answers:

  1. At most once (on the materialization if any)
  2. Since you've materialized the myOrderedIEnumerable any modifications of the initial myNoOrderedList will not be seen:

Simplified example:

 List<string> initial = new List<String>() {
   "a", "z", "e", "d";
 };

 // Nothing will be done at this point (no ordering)
 var ordered = initial.
   .OrderBy(x => x.Property);

 // ordered has not materialized here, so it'll feel Addition
 initial.Add("y"); // <- will be added into ordered 

 // Here on the first loop ordered will be materialized and since
 // initial and ordered are different collection now, we can modify 
 // initial without changing ordered
 foreach (var item in ordered) {
   if (item == "a") {
     initial.Add("b");
     initial.Remove("z");
   } 

   Console.WriteLine(item);
 }

Outcome:

a
d
e
y <- before materialization
z 

Edit: Please, notice, that materization is a tricky thing: it may be called:

  1. Immediately, at the declaration e.g. after .ToList(), .Any(), .FirstOrDefault()
  2. On the first item e.g. .OrderBy (your case)
  3. Never e.g. .Where(), .SkipWhile() - see Magnus's comment

Linq is lazy and perfom materialization as late as possible.

like image 197
Dmitry Bychenko Avatar answered Mar 19 '23 19:03

Dmitry Bychenko