Skip to content
AgileLogics
5 min read

Advanced LINQ & Deferred Execution

Prerequisites: Advanced generics & constraints

LINQ's GroupBy and aggregate operators cover the same ground as Java's stream Collectors:

record Person(string Name, string City);

List<Person> people = new() {
    new("Ada", "London"),
    new("Grace", "New York"),
    new("Al", "London"),
};

var byCity = people.GroupBy(p => p.City);
foreach (var group in byCity) {
    Console.WriteLine($"{group.Key}: {group.Count()}");
}

string names = string.Join(", ", people.Select(p => p.Name));

Most LINQ operators are deferred — building byCity above doesn't actually run the grouping until something enumerates it (the foreach). Calling .ToList() forces immediate execution, useful when a query's source data might change before you're ready to use the results.

Common mistakes

  • Building a LINQ query inside a loop that also modifies the underlying collection, then enumerating it afterward — deferred execution means the query sees the collection's state at enumeration time, not when it was written.