IEnumerable
3 min readIEnumerable
TL;DR
IEnumerable<T> is the minimal "forward-only, read-only, lazy" sequence contract that every LINQ pipeline and foreach loop is built on. Returning it from APIs hides the concrete collection, enables deferred execution so filters compose without intermediate allocations, and lets you stream large or even infinite sequences via yield return — the right default unless callers actually need Count, indexed access, or mutation.
How it works
IEnumerable — Read-Only Forward Iteration
"Use IEnumerable
when you only need to iterate once, forward-only, and want lazy evaluation."
❌ Bad example:
public List<Order> GetActiveOrders()
{
var orders = _repository.GetAll(); // loads everything
return orders.Where(o => o.IsActive).ToList(); // filters in memory
}
// Caller
public void ProcessOrders()
{
List<Order> orders = GetActiveOrders(); // forces concrete type
foreach (var order in orders) { /* ... */ }
}
Returning List<T> exposes mutability, couples caller to implementation, and forces immediate materialization.
✅ Good example:
public IEnumerable<Order> GetActiveOrders()
{
var orders = _repository.GetAll();
return orders.Where(o => o.IsActive); // deferred execution
}
// Caller
public void ProcessOrders()
{
IEnumerable<Order> orders = GetActiveOrders(); // flexible contract
foreach (var order in orders) { /* ... */ }
}
👉 Returns interface, enables lazy evaluation, and hides implementation.
🔥 Using yield return for streaming:
public IEnumerable<Trade> GetTradesForDate(DateTime date)
{
using var reader = _database.ExecuteReader($"SELECT * FROM Trades WHERE Date = '{date}'");
while (reader.Read())
{
yield return new Trade
{
Id = reader.GetInt32(0),
Symbol = reader.GetString(1),
Price = reader.GetDecimal(2)
};
}
}
👉 Streams results one at a time, reducing memory pressure for large datasets.
💡 In trading systems:
- Use IEnumerable
for large result sets from databases (avoid loading millions of trades). - Enable deferred execution so filters/transformations compose efficiently.
- Prevent callers from modifying source collections accidentally.