What is the difference between IEnumerable, ICollection and IList?
Quick Answer
They form a hierarchy of increasing capability: IEnumerable<T> — iterate only (lazy, forward-only). ICollection<T> — adds Count, Add, Remove, Contains. IList<T> — adds integer indexing and Insert/RemoveAt. Accept the least capable one that does the job; there are also read-only variants (IReadOnlyCollection, IReadOnlyList).
It's a capability ladder. IEnumerable<T> just lets you iterate, one pass, forward only, and it can be lazy. ICollection<T> adds a real Count plus add and remove. IList<T> adds positional access — indexing, insert at, remove at. The design guidance is to take the weakest one that meets your needs: if a method only foreaches its input, take IEnumerable<T> so callers can pass anything. For return values I like the read-only interfaces to signal intent. One trap is .Count() on an IEnumerable can iterate the whole sequence, whereas .Count on a collection is instant.
- Parameters: accept
IEnumerable<T>if you only foreach; that lets callers pass arrays, lists, LINQ results, generators. - Return types:
IReadOnlyList<T>communicates “you can index and count this but not mutate it”. IEnumerable<T>.Count()is the LINQ extension and may enumerate everything;ICollection<T>.Countis O(1).IQueryable<T>extendsIEnumerable<T>but builds an expression tree for a provider (EF) to translate.