I learned C# back in 2006, and recently tried to get back into it. I have learned then that they added something called LINQ Extensions to C#3.0. Now I am familiar with extension methods, and I’m just pondering the specifics of those related to IEnumerables.
Earlier today, me and one of my colleagues were debating whether or not the following blocks of code were equivalent:
List<int> integers;
IEnumerable<int> subResult = items.Where(i => IsPrime(i));
IEnumerable<int> orderedResult = subResult.OrderBy(i => i);
versus
List<int> integers;
IEnumerable<int> result = items.Where(i => IsPrime(i)).OrderBy(i => i);
He told me the latest was more efficient because the extension used late querying of it’s source. I’m not quite sure I understood what he meant, and I was wondering if he was right.
They’re equivalent. They both use lazy evaluation / late querying.
What this means is that when the
.Wheremethod is called, it doesn’t perform any actual enumeration of the list, it just keeps a reference to it’s input and the condition it’s going to check and stores those references. When theGetEnumeratormethod is later called on.Where‘s result,.Wherekicks into action.Same thing with
.OrderBy. It doesn’t actually do enumeration of the list until.GetEnumeratoris called.This stuff can be hard to understand but there’s a few really good ways to learn about it. First is write up a simple example like you have, preferrably split onto multiple lines, with a simple for-each loop to iterate all the items. The debug the code and step through line-by-line. See how the debugger jumps around. It’s very confusing at first, but run through a few times and you’ll understand how lazy evaluation works.
Jon Skeet also has a wonderful demo for visualizing LINQ.
https://msmvps.com/blogs/jon_skeet/archive/2008/02/20/visual-linq-watch-query-expressions-as-they-happen.aspx