How do arrays in C partially implement IListT?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In C#, arrays behave like collections and can be treated as list-like structures in many APIs. That leads to a common confusion: arrays can appear to implement IList<T>, yet methods such as Add still fail. The reason is that arrays are fixed-size collections with partial list semantics, not fully mutable lists.
What Arrays Support Well
Arrays provide strong support for read and indexed-write operations:
- direct index access
Lengthfor element count- enumeration with
foreach - compatibility with many collection interfaces
That is why arrays fit naturally into many APIs expecting sequence-like behavior.
Why List Mutation Methods Fail
IList<T> includes methods that assume dynamic resizing. Arrays cannot change length after allocation.
Element replacement works, but size-changing methods throw at runtime.
Fixed Size Is Not the Same as Immutable
Another misconception is that fixed-size arrays are immutable. They are not.
- immutable means element values cannot change
- fixed size means element count cannot change
If you need true immutability, use immutable collections or expose read-only wrappers.
Interface Perspective and API Contracts
Arrays can be consumed through interfaces such as IEnumerable<T> and IReadOnlyList<T> safely because those contracts do not require resizing.
API design guidance:
- use
IReadOnlyList<T>when caller should read by index - use
IEnumerable<T>when only iteration is needed - avoid exposing
IList<T>when backing structure cannot resize
Clear contracts prevent surprise exceptions in downstream code.
Covariance and Runtime Type Safety
Reference-type arrays in .NET are covariant, which can lead to runtime errors.
The runtime blocks invalid element assignment to preserve actual array element type.
Choosing Between Array and List<T>
Use arrays when:
- size is known up front
- fixed memory layout matters
- interop APIs require arrays
Use List<T> when:
- size changes during processing
- inserts and deletes are required
- you need full mutable list operations
Conversion is straightforward:
Performance Considerations
Arrays are compact and fast for index access. List<T> adds resizing logic and capacity management but offers flexibility. In many cases, a good pattern is:
- accumulate data in
List<T> - call
ToArray()once for final fixed representation
This combines easy mutation during construction with efficient read access later.
Common Pitfalls
- Casting arrays to
IList<T>and expectingAddorRemoveto work. - Treating fixed-size collections as immutable collections.
- Exposing
IList<T>in APIs backed by arrays. - Ignoring array covariance runtime checks for reference types.
- Using arrays in workflows that require frequent insertion and deletion.
Summary
- Arrays support indexing and enumeration but cannot change size.
- They behave like lists for some operations and fail for resize operations.
- Fixed size does not imply immutability of element values.
- Use
IReadOnlyList<T>for array-backed API contracts. - Choose
List<T>when dynamic collection growth is required.

