Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are First() and Last() on IEnumerable<> really the first and last?

I recently came to realize that you shouldn't make any assumptions on the implementation of an IEnumerable (for example that you can't assume that when you make changes to one of the objects that came from the IEnumerable during a foreach loop, that after the loop (or even after each iteration) the changed object can be found in the IEnumerable.

So after re-examining my assumptions about IEnumerable, I came to the conclusion that in fact the only thing you can know for sure is that it allows you to traverse all the elements of a collection, where a collection (not ICollection per se) can be anything.

Another assumption that I think that I cannot make is that the order of the underlying collection is something specific. Theoretically you could get the items in a different order everytime you loop over them I'd say.

Now to return to my original question, taking the above into account, First() and Last() could return different items every time (theoretically looking at what an IEnumerable is)?

Exra info: Of course usually this will be fine because the IEnumerable is implemented by something that is ordered. But what if the IEnumerable makes calls to a webservice to get its elements.

Background info: I was thinking about this because I wanted to do something specific for the first and last element in a foreach loop. So I checked if(currentElement == Enumerable.Last())

like image 428
Matthijs Wessels Avatar asked Jan 20 '23 05:01

Matthijs Wessels


2 Answers

First() gets an enumerator and return first value that it founds. Last() most often iterates through the whole collection and returns element one before reaching the end of enumeration. And right, that's all you know for sure. Specifically, collection can be infinite and then Last() will never return.

There is very helpful series of articles about LINQ operators by Jon Skeet - see Edulinq. He describes every single LINQ operator and discuss all the ideas and assumptions in details. It gives very good insight in how all those things really work.

like image 171
NOtherDev Avatar answered Feb 24 '23 02:02

NOtherDev


So I checked if(currentElement == Enumerable.Last())

Last() is really the last, but calling it enumerates your Enumerable. It is not free of cost or side-effects.

And that also gives you the definition of Last() : the last element that an iteration currently yields. Change the list and you may have another Last().

like image 42
Henk Holterman Avatar answered Feb 24 '23 03:02

Henk Holterman