Where
is not a subcollection, it's a filter. The difference goes to the heart of how LINQ works.
You can think of Where
as, roughly, saving a reference to the original IEnumerable
, along with some code that checks for the condition, and some state which says how far through it has gone. When you do getNext()
on the output of Where
, the piece of code goes through the original IEnumerable
until it finds an element which satisfies the condition, then returns it (or gets to the end of the original IEnumerable
, which means that it's also at the end of Where
).
This is lazy evaluation - it only looks at as many terms as it needs to at any one time. So the original IEnumerable
has to be present and unmodified the whole way along. If you call ToList()
, the evaluation will take place straight away - all the elements will be extracted and put into a list before continuing.
The best stuff to read about this is by C# and Linq god Jon Skeet. His posts include reimplementations of all the main Linq functions with detailed discussion of implementation issues, so that you can see exactly how they (probably) work.