BuildQuill
C# learning path
21 of 25
Lesson 21 of 25
Lesson 21Beginner21 min

C# LINQ

Express filtering, projection, ordering, grouping, and aggregation as readable data queries while understanding deferred execution and repeated work.

Before this lesson

  • Collections
  • Generics
  • Delegates and lambdas
  • Loops

Translate a loop-based query into a LINQ pipeline

Distinguish filtering from projection and materialization

Predict deferred execution and avoid accidental repeated queries

The short answer

LINQ is a set of strongly typed query operations for sequences. Where filters, Select transforms, OrderBy sorts, GroupBy groups, and aggregate methods such as Count and Sum produce summaries.

01

A query describes the result you want

An explicit loop explains how to visit items, test them, and append matches. LINQ lets code describe the same transformation through named operations. Where means keep items satisfying a predicate; Select means produce a new value from each item.

LINQ does not replace the need to understand loops. Sequence operators still enumerate data, call delegates, allocate results when materialized, and may perform substantial work. The higher-level vocabulary helps when it makes the transformation easier to verify.

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

IEnumerable<int> squaresOfEvenNumbers = numbers
  .Where(number => number % 2 == 0)
  .Select(number => number * number);

Console.WriteLine(string.Join(", ", squaresOfEvenNumbers));

Expected output

4, 16
02

Filter, project, order, and summarize are different steps

Where keeps or removes original elements. Select changes the shape by mapping each element to another value. OrderBy and ThenBy define ordering. Count, Any, All, Sum, Average, Min, and Max answer aggregate questions. Keeping each step honest makes a pipeline readable from left to right.

Use Any(predicate) to ask whether at least one match exists rather than Count(predicate) > 0. Use FirstOrDefault only when a default or absence has a defined meaning; otherwise a missing result may hide a broken assumption.

QuestionOperatorResult shape
Which items qualify?WhereA filtered sequence
What should each become?SelectA transformed sequence
In what order?OrderBy / ThenByAn ordered sequence
Does any item qualify?Anybool
What is the total?SumOne numeric value
03

Many queries are deferred

Where and Select usually return a description of work rather than executing immediately. Enumeration—foreach, ToList, Count, and similar terminal use—runs the query. This deferred execution lets pipelines compose and observe current source contents, but it can surprise you when the source changes or an expensive query is enumerated twice.

ToList and ToArray materialize a snapshot now. Materialize when you need stable results, repeated enumeration would be costly, or a later layer should receive a concrete collection. Do not call ToList between every operator; it creates unnecessary intermediate collections.

C#
List<int> numbers = new List<int> { 1, 2, 3 };
IEnumerable<int> positives = numbers.Where(number => number > 0);

numbers.Add(4);

Console.WriteLine(string.Join(", ", positives)); // includes 4
04

A practical projection keeps the source model intact

A report often needs a different shape from the domain objects. Select can project orders into display strings or dedicated report records without adding presentation-only properties to Order. GroupBy can organize elements by category, but nested group pipelines become harder to debug; name intermediate queries when that improves clarity.

Database-backed LINQ providers may translate expression trees into SQL rather than run ordinary in-memory methods. Not every C# operation can be translated, and performance depends on the generated query. The pipeline vocabulary transfers, but inspect provider documentation and generated queries in real data applications.

Good habits

  • Use plural names for sequences and singular names for lambda parameters.
  • Avoid side effects inside Where and Select; queries are easier to reason about as transformations.
  • Materialize deliberately at an ownership or execution boundary.
  • Split a long pipeline into named stages when it tells the story better.

Quick knowledge check

Answer before you reveal.

01Does Where change each element?

No. It filters the sequence. Select transforms elements.

02When can a deferred query run more than once?

Each enumeration can execute it again unless the results were materialized into a collection.

Practice challenge

Now build it without copying.

From a list of order totals, select values from 20 through 100, sort descending, apply a 5% discount with Select, materialize once, and print the count and sum.

You are done when

  • Where expresses the range rule
  • Select transforms rather than mutates the original list
  • The query is materialized once before repeated reporting

Stretch: Write the same operation with a foreach loop and compare which version exposes state and which exposes intent more clearly.

Open challenge in playground

Lesson checkpoint

One small step locks it in

Mark this lesson complete, then keep the momentum going.

Complete and continue

Clear up the details

Frequently asked questions

Is method syntax better than query syntax?

Both compile into standard query operations. Method syntax covers every operator and is common; query syntax can read well for joins and multi-stage queries. Choose clarity and team convention.

What is IEnumerable<T>?

It is the core generic contract for a sequence that can be enumerated. It does not promise indexed access, mutability, or one-time versus deferred computation.

Can LINQ be slow?

Yes, like any code. Repeated enumeration, unnecessary materialization, poor database translation, and large sorts can cost time or memory. Express the query clearly, then measure real workloads.