Codectionary / Developer documentation / C#

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().

Syntax

collection.Where(condition).Select(transform)

Examples

Where(): Filtering a Collection

Keeping only elements that satisfy a condition.

List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

var evens = numbers.Where(n => n % 2 == 0).ToList();
Console.WriteLine(string.Join(", ", evens));  // 2, 4, 6, 8, 10

Select(): Transforming a Collection

Producing a new sequence by applying a transformation to every element.

List<string> names = new List<string> { "fola", "zain", "jamal" };

var capitalized = names.Select(n => n.ToUpper()).ToList();
Console.WriteLine(string.Join(", ", capitalized));  // FOLA, ZAIN, JAMAL

var lengths = names.Select(n => n.Length).ToList();
Console.WriteLine(string.Join(", ", lengths));  // 4, 4, 5

Chaining Where and Select

The real power of LINQ: combining operations into a readable pipeline.

List<string> words = new List<string> { "apple", "hi", "banana", "ok", "cherry" };

var result = words
    .Where(w => w.Length > 2)
    .Select(w => w.ToUpper())
    .OrderBy(w => w)
    .ToList();

Console.WriteLine(string.Join(", ", result));  // APPLE, BANANA, CHERRY

LINQ Query Syntax

An alternative, SQL-like syntax that compiles down to the same method calls.

List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };

var evens = from n in numbers
            where n % 2 == 0
            select n;

Console.WriteLine(string.Join(", ", evens));  // 2, 4, 6

Best practices

  • Chain Where() before Select() when doing both, so filtering happens on the smaller, reduced set first for better performance
  • Remember LINQ queries are lazy - nothing actually executes until you iterate the result or call ToList()/ToArray()/Count(), etc.
  • Prefer method syntax (.Where().Select()) for most code - reach for query syntax (from...where...select) mainly when it reads more naturally, like with joins
  • Materialize a query with .ToList() when you need to use the result multiple times, to avoid re-running the query (and its source) each time

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 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.
LINQ Element & Quantifier Operators
Element operators retrieve a single item from a sequence: First()/FirstOrDefault() for the first match, Single()/SingleOrDefault() for exactly one match, with 'OrDefault' variants returning a default value instead of throwing when nothing matches. Quantifier operators return a bool describing the sequence as a whole: Any() checks if at least one element matches, and All() checks if every element matches.