Syntax
var query = collection.Where(predicate); // not executed yetExamples
Queries Are Not Executed Immediately
Defining a query does not run it - only enumerating it does.
List<int> numbers = new List<int> { 1, 2, 3 };
var query = numbers.Where(n =>
{
Console.WriteLine($"Checking {n}");
return n > 1;
});
Console.WriteLine("Query defined, but not run yet");
var result = query.ToList(); // THIS is when "Checking..." actually printsA Deferred Query Re-Reads the Source
Because execution is deferred, changes to the source between enumerations are picked up.
List<int> numbers = new List<int> { 1, 2, 3 };
var evens = numbers.Where(n => n % 2 == 0);
numbers.Add(4);
numbers.Add(6);
Console.WriteLine(string.Join(", ", evens)); // 2, 4, 6 - includes the new items!Forcing Immediate Execution
Calling ToList(), ToArray(), or Count() forces the query to run right away and captures a snapshot.
List<int> numbers = new List<int> { 1, 2, 3 };
List<int> evensSnapshot = numbers.Where(n => n % 2 == 0).ToList(); // runs NOW
numbers.Add(4);
Console.WriteLine(string.Join(", ", evensSnapshot)); // 2 - unaffected by the later AddBest practices
- Call .ToList() or .ToArray() when you need a stable snapshot of results that will not change if the underlying source is modified later
- Be cautious about enumerating the same deferred query multiple times when the source (or the query itself) is expensive to compute - each enumeration re-runs the whole pipeline
- Remember methods like Count(), Sum(), First(), and ToList() all trigger immediate execution of everything before them in the chain
- Watch for 'multiple enumeration' bugs where a deferred query is enumerated more than once unintentionally (e.g. once in an if check, again in a loop) - materialize it first with .ToList() to avoid redundant work
At a glance
- Purpose
- Applications on the .NET platform
- File extension
- .cs
- Runs in
- .NET runtime
- Usually used with
- .NET SDK and libraries
Specifications & further reading
Related C# documentation
Lambda Expressions
A lambda expression is a compact way to represent an anonymous function - a block of code that can be passed around as a value, using the => (goes to) operator. Lambdas work with delegate types and functional interfaces like Func<> and Action<>, letting you write inline logic without a full named method. Lambdas are the foundation that makes LINQ's fluent, expressive query syntax possible.LINQ Basics: Where & Select
LINQ (Language Integrated Query) provides a consistent, declarative way to query collections, databases, and XML directly within C# syntax. Where() filters a sequence down to elements matching a condition, and Select() transforms each element into something new (a projection). Both are 'lazy' - they build a query that only actually runs when you iterate over the result or call something like ToList().LINQ Ordering & Grouping
OrderBy() and OrderByDescending() sort a sequence by a key you specify, with ThenBy() for secondary sort keys on ties. GroupBy() splits a sequence into groups based on a key selector, producing a sequence of groups where each group itself is enumerable and has a Key property identifying which group it represents.LINQ Aggregation: Sum, Count, Average
LINQ provides built-in aggregation methods that reduce a sequence down to a single summary value: Count() for the number of elements, Sum() for a total, Average() for the mean, and Max()/Min() for extremes. Aggregate() is the general-purpose version, letting you define fully custom accumulation logic when the built-in methods aren't enough.
A lambda expression is a compact way to represent an anonymous function - a block of code that can be passed around as a value, using the => (goes to) operator. Lambdas work with delegate types and functional interfaces like Func<> and Action<>, letting you write inline logic without a full named method. Lambdas are the foundation that makes LINQ's fluent, expressive query syntax possible.LINQ Basics: Where & Select
LINQ (Language Integrated Query) provides a consistent, declarative way to query collections, databases, and XML directly within C# syntax. Where() filters a sequence down to elements matching a condition, and Select() transforms each element into something new (a projection). Both are 'lazy' - they build a query that only actually runs when you iterate over the result or call something like ToList().LINQ Ordering & Grouping
OrderBy() and OrderByDescending() sort a sequence by a key you specify, with ThenBy() for secondary sort keys on ties. GroupBy() splits a sequence into groups based on a key selector, producing a sequence of groups where each group itself is enumerable and has a Key property identifying which group it represents.LINQ Aggregation: Sum, Count, Average
LINQ provides built-in aggregation methods that reduce a sequence down to a single summary value: Count() for the number of elements, Sum() for a total, Average() for the mean, and Max()/Min() for extremes. Aggregate() is the general-purpose version, letting you define fully custom accumulation logic when the built-in methods aren't enough.