IList
3 min readIList — Indexed Access Collections
"Use IList
when you need random access by index, or when Insert/RemoveAt operations are required."
❌ Bad example:
public IEnumerable<Trade> GetRecentTrades()
{
return _trades.OrderByDescending(t => t.Timestamp).Take(10);
}
// Caller
public void DisplayLastTrade(IEnumerable<Trade> trades)
{
var lastTrade = trades.Last(); // enumerates entire sequence
Console.WriteLine(lastTrade.Symbol);
}
Using .Last() on IEnumerable
âś… Good example:
public IList<Trade> GetRecentTrades()
{
return _trades.OrderByDescending(t => t.Timestamp).Take(10).ToList();
}
// Caller
public void DisplayLastTrade(IList<Trade> trades)
{
var lastTrade = trades[trades.Count - 1]; // O(1) indexed access
Console.WriteLine(lastTrade.Symbol);
}
👉 IList
🔥 When Insert/RemoveAt matters:
public class OrderBook
{
public IList<Order> BuyOrders { get; } = new List<Order>();
public void InsertOrderAtPrice(Order order)
{
// Binary search to find insertion point
int index = BuyOrders.BinarySearch(order, new PriceComparer());
if (index < 0) index = ~index;
BuyOrders.Insert(index, order); // insert at specific position
}
}
👉 IList
🔥 Avoiding unnecessary copies:
// ❌ Bad: forces caller to know concrete type
public List<decimal> CalculatePrices(List<decimal> basePrices)
{
for (int i = 0; i < basePrices.Count; i++)
basePrices[i] *= 1.05m;
return basePrices;
}
// âś… Good: accepts interface, returns interface
public IList<decimal> CalculatePrices(IList<decimal> basePrices)
{
for (int i = 0; i < basePrices.Count; i++)
basePrices[i] *= 1.05m;
return basePrices;
}
👉 Accepting IList
đź’ˇ In trading systems:
- Use IList
for order books where indexed access is critical for price levels. - Enable efficient batch processing with index-based loops (faster than foreach for large arrays).
- Prefer IEnumerable
unless random access is genuinely needed—narrower contract.
Questions & Answers
A: IList
A: Not strictly. List
A: Only if callers need indexed access or Insert/RemoveAt. Otherwise, IEnumerable
A: Yes. Arrays are fixed-size, so Add/Remove throw NotSupportedException. Check IsReadOnly before assuming mutability. Prefer IReadOnlyList
A: Arrays implement IList
A: Use for (int i = 0; i < list.Count; i++) when you need the index or modify elements by index. Use foreach for clarity when index isn't needed.
A: O(n) for List
A: Yes. Arrays implement IList
A: Use List
A: Throws IndexOutOfRangeException (arrays) or ArgumentOutOfRangeException (List