What is the difference between IEnumerable, ICollection and IList?
Quick Answer
They form a hierarchy of capability. IEnumerable<T> — iterate only (foreach). ICollection<T> — adds Count, Add, Remove, Contains. IList<T> — adds index access and Insert/RemoveAt. Expose the least capable interface a caller needs.
It's a capability ladder. IEnumerable<T> just lets you iterate. ICollection<T> adds count, add, remove and contains. IList<T> adds indexing and insert-at-position. The principle I follow is to expose the least powerful one that does the job — return IEnumerable<T> or IReadOnlyList<T> from a method so callers can't mutate my internal collection, and only take IList<T> as a parameter when the method really does add or remove items.
- Return
IEnumerable<T>from a method when the caller should only read/iterate — it also allows lazy/streamed results. - Return
IReadOnlyList<T>/IReadOnlyCollection<T>when the caller needsCountor indexing but shouldn't mutate. - Use
ICollection<T>/IList<T>for parameters where the method genuinely adds or removes items. - Beware: returning
IEnumerable<T>that's actually a deferred query — the caller may enumerate it multiple times and re-run it. Materialise if needed.