🎯 Understanding LINQ Deferred Execution in C# (with a Simple Example)

PriyaPriya
3 min read

LINQ (Language Integrated Query) is one of C#’s most elegant features, enabling expressive querying over collections. But there's one subtle yet powerful behavior that often catches developers off guard:
👉 Deferred Execution.

Let’s break it down with a simple, relatable example.


✅ Scenario: Multiply Numbers by 10

Suppose you have a list of numbers and want to multiply each by 10 and print the result.

var lst = new List<int> { 2, 5, 6 };

// Define the LINQ query (this does NOT execute yet — deferred execution)

var query = lst.Select(x => 10 * x);

lst.Add(8); // Modify the list AFTER defining the query

// Deferred execution happens here — during enumeration

foreach (var number in query) // You could also use query.ToList()

{

Console.WriteLine(number);

}

✅ Output:

20

50

60

80

☑️ Key Insight:

The result includes 80 because LINQ executes the query at the time of iteration, not when it’s defined.


🔍 What’s Going On?

Even though we added 8 after defining the query, the result still includes it.
Why?
Because LINQ uses deferred execution by default — the query is only evaluated when you actually iterate or access it.


🔁 What is Deferred Execution?

Deferred execution means the query isn't run when it's written — it's executed only when used.

This happens when you:

  • Use a foreach loop

  • Call .ToList(), .ToArray(), .Count(), .First(), etc.

That’s why changes made after query definition (but before execution) still affect the result.


💬 Glossary Box

🧾 Materialization
The act of converting a query into a concrete structure like a List or Array, triggering immediate execution.

Example:

var results = query.ToList(); // Forces materialization


🧠 Visual Analogy: LINQ is Like a Recipe

Think of a LINQ query as a recipe:

  • 📖 The recipe (query) is written

  • 🧑‍🍳 But the cooking (execution) happens later

If you change the ingredients (data source) before cooking starts, the final dish will reflect the latest changes — that’s deferred execution in action.


⚡ Immediate vs Deferred Execution

Let’s compare:

// ❌ Deferred Execution

var query = lst.Select(x => x * 10); // Not executed yet

// ✅ Immediate Execution

var results = lst.Select(x => x * 10).ToList(); // Executed immediately

With .ToList(), you're taking a snapshot of the current data — future changes to the source list won’t affect the results.


✅ When Should You Force Execution?

Use immediate execution when:

  • ✅ You need a consistent snapshot of data

  • ✅ You're in multi-threaded environments

  • ✅ The data source can change

  • ✅ You want to avoid recomputation

  • ✅ You want to filter early for performance


✨ Try It Yourself!

🧪 Run this example interactively:


📚 Learn More

Related Topics:

  • IEnumerable vs IQueryable

  • Materialization using .ToList()

  • Projection with .Select()

  • Filtering with .Where()


🏁 Final Thoughts

LINQ is incredibly powerful — but it’s essential to know when your query runs.

Just because a query is defined doesn’t mean it’s executed right away.
In fact, LINQ waits until the last moment — and that’s often a feature, not a bug.

0
Subscribe to my newsletter

Read articles from Priya directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Priya
Priya