C#
IList
ICollection
Collection
programming-best-practices

Returning 'IList' vs 'ICollection' vs 'Collection'

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

When choosing whether a method should return IList<T>, ICollection<T>, or Collection<T>, the real question is how much capability you want to promise to callers. In API design, the general rule is to return the least specific type that still expresses the operations the caller is supposed to rely on.

Understand What Each Type Promises

These types are related but not equivalent.

  • 'ICollection<T> promises enumeration, Count, and basic add and remove semantics.'
  • 'IList<T> adds ordering and index-based access.'
  • 'Collection<T> is a concrete class intended for subclassing and customization.'

That means returning one of them is not only a technical choice. It is also part of the contract you publish.

Return IList<T> Only If Indexing Is Part of the Contract

If callers need items[0], IndexOf, or insertion at a specific position, IList<T> may be the right return type.

csharp
1public IList<string> GetOrderedNames()
2{
3    return new List<string> { "Ada", "Grace", "Linus" };
4}

This tells the caller that ordering and positional access are meaningful. That is a stronger promise than simple collection membership.

If that promise is not intentional, returning IList<T> exposes more mutating surface area than necessary.

Return ICollection<T> When Only Collection Semantics Matter

If the caller only needs to enumerate, count, or add and remove items without index semantics, ICollection<T> is a narrower and often better contract.

csharp
1public ICollection<string> GetTags()
2{
3    return new HashSet<string> { "api", "backend", "security" };
4}

This avoids implying that the result is meaningfully ordered.

In many business APIs, this is already more mutability than necessary. If callers should not mutate the result, a read-only abstraction is usually better.

Return Collection<T> Only for a Specific Reason

Collection<T> is a concrete class, not just an interface. Returning it is usually appropriate only if the concrete type itself is important, such as when the caller needs subclass-specific behavior or when your API is tightly coupled to that class.

csharp
1using System.Collections.ObjectModel;
2
3public Collection<int> BuildCollection()
4{
5    return new Collection<int> { 1, 2, 3 };
6}

Most APIs should not return Collection<T> by default. Doing so exposes an implementation choice that callers usually do not need to know.

Prefer Read-Only Return Types When Mutation Is Not Intended

In modern API design, the more common question is often not IList<T> versus ICollection<T>, but whether either of them is too permissive.

If the caller should read but not modify the result, prefer a read-only abstraction such as IReadOnlyList<T> or IReadOnlyCollection<T>.

csharp
1public IReadOnlyList<string> GetNames()
2{
3    return new List<string> { "Ada", "Grace", "Linus" };
4}

This communicates intent much more clearly than returning a mutable interface and merely hoping callers will not mutate it.

Design from the Consumer’s Needs

A useful rule is to ask: what operations should the consumer rely on?

If the answer is:

  • “just enumerate and count,” return a narrower collection abstraction
  • “indexing matters,” return a list-like abstraction
  • “the exact collection implementation matters,” return the concrete type only if that is truly intentional

Returning the broadest or most convenient type from the implementation side is often the wrong choice for long-term API clarity.

Avoid Leaking Implementation Details

If your method internally uses List<T>, that does not mean the signature should return IList<T> or List<T>. The internal storage choice and the external contract are separate decisions.

That separation matters because it gives you freedom to change the implementation later without breaking consumers.

A Practical Guideline

For most public APIs:

  • prefer read-only interfaces when callers should not modify the data
  • prefer IList<T> only when positional semantics matter
  • use ICollection<T> when collection membership matters but indexing does not
  • return Collection<T> only when you specifically mean that concrete type

That guidance keeps the API honest and easier to evolve.

Common Pitfalls

  • Returning IList<T> when callers do not actually need indexing.
  • Returning Collection<T> just because it was convenient to instantiate.
  • Exposing mutable collection interfaces when the result should really be read-only.
  • Confusing the internal implementation type with the public contract.
  • Making the signature broader than necessary and reducing future flexibility.

Summary

  • Return the least specific type that still matches the intended contract.
  • Use IList<T> when ordering and index-based access are part of the API.
  • Use ICollection<T> when only collection semantics matter.
  • Return Collection<T> only if the concrete type itself is important.
  • In many modern APIs, a read-only interface is a better choice than any of the mutable options.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions