What is IEnumerable in .NET?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
IEnumerable is the .NET interface that represents a sequence you can iterate over. In modern C#, you will usually work with IEnumerable<T>, the generic version, because it supports strongly typed iteration and is the foundation for foreach, LINQ, and many lazy data pipelines.
What IEnumerable Means
At the interface level, IEnumerable says one simple thing: “this type can return an enumerator.” That enumerator exposes the sequence one item at a time.
In everyday code, that gives you the ability to write:
The collection can be a list, an array, a generated sequence, or something that reads values from another source. The caller does not need to know how the values are stored. It only needs to know that it can iterate through them.
The non-generic IEnumerable lives in System.Collections. The generic IEnumerable<T> lives in System.Collections.Generic and is the one you should prefer in most new code.
Why IEnumerable<T> Is Useful
Programming against IEnumerable<T> is often better than programming against List<T> when your method only needs to read a sequence. It keeps the API flexible.
The SumAdults method works with arrays, lists, or any other enumerable source. By depending on the smaller abstraction, the method accepts more inputs and communicates that it does not need list-specific features such as indexing or mutation.
Deferred Execution
One of the most important behaviors tied to IEnumerable<T> is deferred execution. Many LINQ operations do not run immediately. They build a query that executes later when you iterate over it.
This prints 2, 4, and 6 because the query is evaluated when foreach runs, not when Where is called.
That behavior is powerful, but it also means repeated enumeration can repeat work. If a query is expensive or depends on external state, materialize it with ToList() when you need a stable snapshot.
Creating Your Own Enumerable Sequence
You do not need to implement the full enumerator pattern manually in most cases. C# provides yield return, which makes custom enumerables easy to write.
This is still an IEnumerable<int>, but the values are produced lazily, one at a time, as the caller iterates.
That pattern is useful for paging, streaming, parsing, and any workflow where you do not want to build the full result eagerly.
IEnumerable<T> Versus IQueryable<T>
A common source of confusion is IEnumerable<T> versus IQueryable<T>. IEnumerable<T> represents in-memory iteration logic. IQueryable<T> represents a query that another provider, such as Entity Framework, may translate into SQL.
If you call LINQ operators on IEnumerable<T>, the work usually happens in .NET code. If you keep the query as IQueryable<T>, the provider may push the work to a database. Knowing where execution happens matters for performance.
Common Pitfalls
The most common mistake is accepting IEnumerable<T> and then enumerating it many times without realizing the cost. If the source is lazy, remote, or computationally expensive, every pass can redo the work.
Another problem is returning IEnumerable<T> from a method that depends on disposable resources such as a database context or file reader. If the resource is gone before enumeration starts, the sequence fails later and far away from the original call.
Developers also sometimes expose List<T> in APIs when they only need read-only iteration. That couples the caller to an unnecessary concrete type.
Finally, do not confuse IEnumerable<T> with “supports random access.” You can iterate it, but you cannot assume indexing, counting efficiency, or mutation support unless a stronger interface is present.
Summary
- '
IEnumerable<T>represents a sequence that can be iterated.' - It is the common abstraction behind
foreachand many LINQ operations. - Prefer it in APIs when you only need read-only iteration.
- Many enumerable queries are lazy and execute only when iterated.
- Use
yield returnto build custom lazy sequences cleanly.

