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

Read the syntax

LINQ methods transform IEnumerable<T> sequences. Where keeps values matching a predicate; Select projects each value into a new one.

ToList materializes results immediately. Without it, many LINQ queries run when enumerated, so changes to the source may affect later results. Query syntax is another form of the same operations.

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
  1. Keeping only elements that satisfy a condition.
  2. LINQ methods transform IEnumerable<T> sequences. Where keeps values matching a predicate; Select projects each value into a new one.
  3. The remainder predicate keeps even values and ToList evaluates the query. Join prints 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> { "john", "zain", "jamal" };

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

var lengths = names.Select(n => n.Length).ToList();
Console.WriteLine(string.Join(", ", lengths));  // 4, 4, 5
  1. Producing a new sequence by applying a transformation to every element.
  2. LINQ methods transform IEnumerable<T> sequences. Where keeps values matching a predicate; Select projects each value into a new one.
  3. One Select maps each name to uppercase text; another maps it to Length. The two materialized lists print names and lengths separately.

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
  1. The real power of LINQ: combining operations into a readable pipeline.
  2. LINQ methods transform IEnumerable<T> sequences. Where keeps values matching a predicate; Select projects each value into a new one.
  3. Where removes the two short words, Select uppercases the remainder, and OrderBy sorts them. The final list prints 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
  1. An alternative, SQL-like syntax that compiles down to the same method calls.
  2. LINQ methods transform IEnumerable<T> sequences. Where keeps values matching a predicate; Select projects each value into a new one.
  3. The query comprehension filters even numbers from the list. Enumerating it for Join prints 2, 4, 6, like a Where call.

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

Runtime & versions

.NET runtime. Feature availability depends on the language and runtime version used by your project; consult the official reference below.

C# language reference

Specifications & further reading