Does LINQ work with IEnumerable?
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
Yes, LINQ absolutely works with IEnumerable<T>, and in fact this is the most common way LINQ is used. LINQ to Objects is the flavor of LINQ that operates on in-memory collections implementing IEnumerable<T>, giving you a declarative, SQL-like syntax for filtering, projecting, and transforming data. Understanding how LINQ interacts with IEnumerable<T> versus IQueryable<T> is key to writing efficient C# code and avoiding performance surprises.
How LINQ Works with IEnumerable
LINQ to Objects is implemented as a set of extension methods defined in the System.Linq namespace. Any type that implements IEnumerable<T> (lists, arrays, dictionaries, hash sets, and custom collections) can use these methods:
Both syntax forms compile to the same extension method calls. The method syntax using lambda expressions is more widely used in practice because it is more flexible and composable.
Deferred vs Immediate Execution
One of the most important concepts to understand about LINQ with IEnumerable<T> is deferred execution. Most LINQ methods do not execute when you call them. Instead, they build up a query that runs only when you iterate over the result:
Deferred execution means the query reflects the current state of the data source at the time of iteration, not at the time of definition. Methods like ToList(), ToArray(), Count(), First(), and Sum() trigger immediate execution because they must consume the entire sequence (or find a specific element) to produce their result.
Common LINQ Methods
Here are the most frequently used LINQ methods on IEnumerable<T>:
Each of these methods returns a new IEnumerable<T> (or IOrderedEnumerable<T> for sorting), allowing you to chain operations together fluently. The entire chain uses deferred execution until you iterate or materialize the results.
IEnumerable vs IQueryable
Understanding the difference between IEnumerable<T> and IQueryable<T> is critical for performance. Both support LINQ, but they execute queries in fundamentally different ways:
With IEnumerable<T>, the lambda expressions are compiled into delegates and executed in your application's memory. With IQueryable<T>, the same lambda expressions are converted into expression trees that a provider (like Entity Framework) translates into SQL. If you accidentally cast an IQueryable<T> to IEnumerable<T> early in a chain, all subsequent filtering happens in memory instead of in the database:
Materializing Results with ToList and ToArray
When you need to force execution and capture the results at a specific point in time, use ToList() or ToArray():
Materialize results when you need to iterate multiple times over the same data, when you need a count without re-executing, or when you want to disconnect from a database context before it is disposed. Avoid materializing unnecessarily large sequences, as it allocates memory proportional to the collection size.
Common Pitfalls
- Iterating a deferred query multiple times re-executes the entire pipeline each time, which can cause performance issues or inconsistent results if the source data changes between iterations.
- Casting a database query to
IEnumerable<T>too early causes all subsequent filtering to happen in memory instead of in SQL, potentially loading millions of rows unnecessarily. - Forgetting to add
using System.Linq;at the top of the file means LINQ extension methods will not appear onIEnumerable<T>, leading to confusing compiler errors. - Adding or removing elements from the source collection while iterating a LINQ query throws an
InvalidOperationExceptionat runtime. - Relying on group ordering from
GroupBywithout an explicitOrderBycan lead to fragile code, since element order within groups is preserved but group ordering is not guaranteed across providers.
Summary
- LINQ works seamlessly with
IEnumerable<T>through extension methods inSystem.Linq, enabling declarative data querying on any in-memory collection. - Most LINQ operations use deferred execution, meaning the query runs only when you iterate the results, not when you define the query.
IEnumerable<T>executes with in-memory delegates whileIQueryable<T>translates to database queries via expression trees. Mixing them up can cause severe performance problems.- Use
ToList()orToArray()to materialize results when you need a snapshot or plan to iterate multiple times. - Chain operations fluently to build readable pipelines. Elements flow through the chain one at a time, keeping memory usage efficient.
Related reading
- Does ListT guarantee insertion order?
- Does .NET 4 have a built-in JSON serializer/deserializer?
- Does .NET 6's PeriodicTimer capture the current SynchronizationContext by default?
- Does .NET have a way to check if List a contains all items in List b?
- Does .NET have icon collections?
- Does .NET provide an easy way convert bytes to KB, MB, GB, etc.?
- Does .NET really use NFA for regular expression engine?
- Does or will C include features for side-effects verification?

OOD Fundamentals
Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.