Why array implements IList?
The remarks section of the documentation for IList
says:
IList is a descendant of the ICollection interface and is the base interface of all non-generic lists. IList implementations fall into three categories: read-only, fixed-size, and variable-size. A read-only IList cannot be modified. A fixed-size IList does not allow the addition or removal of elements, but it allows the modification of existing elements. A variable-size IList allows the addition, removal, and modification of elements.
Obviously, arrays fall into the fixed-size category, so by the definition of the interface it makes sense.
It's a legacy that we have from the times when it wasn't clear how to deal with read only collections and whether or not Array is read only. There are IsFixedSize and IsReadOnly flags in the IList interface. IsReadOnly flag means that collection can't be changed at all and IsFixedSize means that collection does allow modification, but not adding or removal of items.
At the time of .Net 4.5 it was clear that some "intermediate" interfaces are required to work with read only collections, so IReadOnlyCollection<T>
and IReadOnlyList<T>
were introduced.
Here is a great blog post describing the details: Read only collections in .NET
Because an array allows fast access by index, and IList
/IList<T>
are the only collection interfaces that support this. So perhaps your real question is "Why is there no interface for constant collections with indexers?" And to that I have no answer.
There are no readonly interfaces for collections either. And I'm missing those even more than a constant sized with indexers interface.
IMO there should be several more (generic) collection interfaces depending on the features of a collection. And the names should have been different too, List
for something with an indexer is really stupid IMO.
- Just Enumeration
IEnumerable<T>
- Readonly but no indexer (.Count, .Contains,...)
- Resizable but no indexer, i.e. set like (Add, Remove,...) current
ICollection<T>
- Readonly with indexer (indexer, indexof,...)
- Constant size with indexer (indexer with a setter)
- Variable size with indexer (Insert,...) current
IList<T>
I think the current collection interfaces are bad design. But since they have properties telling you which methods are valid (and this is part of the contract of these methods), it doesn't break the substitution principle.
Because not all IList
s are mutable (see IList.IsFixedSize
and IList.IsReadOnly
), and arrays certainly behave like fixed-size lists.
If your question is really "why does it implement a non-generic interface", then the answer is that these were around before generics came along.