What is the difference between List of T and Collectionof T?
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
In .NET, both List<T> and Collection<T> represent ordered mutable collections, but they are designed for different responsibilities. List<T> is the default high performance container for most application code. Collection<T> is an extensibility base class used when mutation needs validation, policy checks, or domain side effects.
When List<T> Is the Right Choice
List<T> is backed by a dynamic array and is optimized for practical everyday operations. Index lookup is constant time, append is amortized constant time, and iteration is fast.
For internal business logic where you only need add, remove, and enumerate, List<T> is usually the simplest and most maintainable option.
Most framework APIs and examples accept IEnumerable<T> or IList<T>, so List<T> integrates naturally.
What Collection<T> Gives You
Collection<T> from System.Collections.ObjectModel wraps an internal list and exposes overridable mutation hooks:
- '
InsertItem' - '
SetItem' - '
RemoveItem' - '
ClearItems'
Those hooks are the main reason to choose it. They let you centralize rules in one place instead of repeating checks across the codebase.
This pattern is useful for domain aggregates, UI binding models, and libraries that need controlled state transitions.
API Design Guidance
For public APIs, exposing concrete mutable collection types can leak implementation details. A common pattern is:
- Store data internally in
List<T>. - Expose read only interfaces such as
IReadOnlyList<T>. - Use
Collection<T>only when callers must interact with a mutable collection that enforces behavior.
This keeps your internal performance characteristics while preserving contract safety.
Performance and Maintenance Tradeoffs
List<T> is typically faster for plain operations because it avoids virtual hook calls and custom logic overhead. Collection<T> adds small indirection, but that cost is usually insignificant compared with the value of centralized invariants.
The real decision should be driven by correctness and maintenance:
- If no mutation policy is needed, prefer
List<T>. - If rules must always run on mutation,
Collection<T>makes that explicit.
A subtle benefit is testability. With Collection<T>, one test suite can validate mutation rules once, instead of checking every call site that modifies a list.
Choosing Between ICollection<T>, List<T>, and Collection<T>
Developers often confuse interface and implementation choices:
- '
ICollection<T>is a capability contract, not a specific data structure.' - '
List<T>is an implementation tuned for speed and convenience.' - '
Collection<T>is an implementation base for policy aware mutation.'
You can accept ICollection<T> in method parameters for flexibility while storing data as List<T> internally.
Common Pitfalls
- Choosing
Collection<T>by default without any custom hooks. This adds abstraction with no payoff. - Exposing mutable
List<T>directly from domain objects. External code can bypass invariants. - Repeating validation checks at call sites instead of centralizing mutation policy.
- Assuming read only view means immutable underlying data. The owner can still mutate internally.
- Micro optimizing collection choice before measuring real bottlenecks.
Summary
- '
List<T>is the default practical choice for mutable ordered data.' - '
Collection<T>is best when you need overridable mutation behavior and domain rules.' - Public API design often benefits from internal
List<T>plus read only exposure. - Choose based on invariants and ownership boundaries, not type popularity.
- Keep collection contracts explicit so callers understand mutability expectations.
Related reading
- What is the difference between List.of and Arrays.asList?
- What is the difference between message queue and message broker?
- What is the difference between ndarray and array in NumPy?
- What is the difference between np.array and np.asarray?
- What is the difference between public, private, and protected inheritance?
- What is the Execute Around idiom?
- What is the difference between log4net and ELMAH?
- What is the difference between ManualResetEvent and AutoResetEvent?

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.