Why array implements IList?

Related searches

See the definition of System.Array class

public abstract class Array : IList, ...

Theoretically, I should be able to write this bit and be happy

int[] list = new int[] {};
IList iList = (IList)list;

I also should be able to call any method from the iList

 ilist.Add(1); //exception here

My question is not why I get an exception, but rather why Array implements IList?

Why array implements IList?, This member is an explicit interface member implementation. It can be used only when the Array instance is cast to an IList interface. Applies to .NET. 5.0 Preview 8� An array is a .NET intrinsic. It holds items of the same type, but it is of a fixed size. Once you create an array with x elements, it cannot grow or shrink. IList defines the interface for a list, and also implements IEnumerable. List implements the IList interface; it is a concrete type of list.

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 defition of the interface it makes sense.

Array.IList.Add(Object) Method (System), Provides methods for creating, manipulating, searching, and sorting arrays, However, it is still considered a collection because it is based on the IList interface. Why array implements IList? (4) Because not all IList s are mutable (see IList.IsFixedSize and IList.IsReadOnly ), and arrays certainly behave like fixed-size lists.

Because not all ILists 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.

Array Class (System), Inside the method, you should use var, instead of IList or List. When your data source changes to come from a method instead, your onlySomeInts method will survive. The reason to use IList instead of List as parameters, is because many things implement IList (List and [], as two examples), but only one thing implements List.

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

Public Sub CopyTo(ByVal array As Array, ByVal index As Integer) Implements ICollection.CopyTo For i As Integer = 0 To Count - 1 array.SetValue(_contents(i), index) index += 1 Next End Sub Public ReadOnly Property Count() As Integer Implements ICollection.Count Get Return _count End Get End Property Public ReadOnly Property IsSynchronized() As

Definition of IList interface is "Represents a non-generic collection of objects that can be individually accessed by index.". Array completely satisfies this definition, so must implement the interface. Exception when calling Add() method is "System.NotSupportedException: Collection was of a fixed size" and occurred because array can not increase its capacity dynamically. Its capacity is defined during creation of array object.

We can use the interface to implement another collection. For example we can instantiate IList object to array. Try to understand below code. class Program { static void Main(string [] args) { IList ilist = new int [10]; ilist.Add(100); Console.ReadLine(); } } We have used object of IList interface to define integer array. By nature IList

A one-dimensional array S[] implements the interface System.Collections.Generic.IList<S> (IList<S> for short) and its base interfaces. Accordingly, there is an implicit conversion from S[] to IList<S> and its base interfaces.

If Collection<T> does not meet some requirement (e.g., the collection must not implement IList), use a custom collection by implementing IEnumerable<T>, ICollection<T>, or IList<T>. ️ DO use ReadOnlyCollection<T> , a subclass of ReadOnlyCollection<T> , or in rare cases IEnumerable<T> for properties or return values representing read-only

IEnumerable<t> in this way is an example of a leaky abstraction! Array implements IEnumerable so you might actually have an Array, but the point is that IEnumerable tells you that you have something you can Enumeratebut you are not meant to Add or Remove from it as in a List.

Comments
  • Good question. I never liked the idea of fat interfaces (that’s the technical term for this kind of design).
  • @Henk, see: blogs.msdn.com/b/bclteam/archive/2004/11/19/267089.aspx
  • Does anybody actually care about LSP? It seems quite academic to me.
  • @Gabe, then you need to work with larger codebases. Implementing a behavior (inheriting from an interface) and then simply ignoring the things you don't like/can't support leads to smelly, obfuscated, casting and finally: buggy code.
  • @Gabe its the collection which implies mutability not its contained entities. You can make your class member of a type that implements both IRWList<> and IReadList<>, use if as IRWList<> internally in your class and expose it as IReadList. Yes, you have to put complexity somewhere, but I just don't see how that applies to disregarding LSP as a very good design principle (did not know about the IsReadOnly property though which makes IList more complex from a consumers standpoint)
  • thanks for the answer. But I rather leave the question as is. The reason is simple. Interface is a public contract. If one implements it, one must fully implement all the members, otherwise it breaks LSP and generally smells bad, is it not?
  • It does break LSP. If it didn't list.Add(item) should add item to the list regardless of the concrete type. Except for exceptionel cases. In the array implementation in throws an exception in a non-exceptionel case, which in it self is bad practice
  • @smelch I'm sorry but you got LSP wrong then. An array does not implement add and thus can't be substituted for something that does when that ability is required.
  • I concede that it technically does not violate LSP only because the documentation states you should check the IsFixedSize and IsReadOnly properties, it definitely violates the Tell, Don't Ask principle and Principle of least surprise. Why implement an interface when you're just going to throw exceptions for 4 out of the 9 methods?
  • Some time has passed since the original question. But now with .Net 4.5, there are additional interfaces IReadOnlyList and IReadOnlyCollection.
  • I guess they would have ended up with a lot of interfaces. IListFixedSize, IListReadOnly...
  • that'a actually a good answer from the documentation's point of view. But to me it rather looks like a hack. Interfaces must be thin and simple in order for a class to implement all the members.