Why System.Array class implements IList but does not provide Add()

It does provide Add, but by throwing a NotSupportedException (see MSDN), because the size of an array is fixed.

The reason why you get a compilation error, instead, is because the interface is implemented explicitly, so if you want to call the method you need to cast to IList. See this C# guide about explicit interface implementation.


Yes, it seems that it should have been a better design if System.Array had implemented IReadOnlyList or alike interface. However, IReadOnlyList<T> appeared in .Net 4.5 while System.Array stays from the initial .Net 1.0. Microsoft, IMHO, did their best and hid Add via explicit interface implementation

http://referencesource.microsoft.com/#mscorlib/system/array.cs,156e066ecc4ccedf

  ...
int IList.Add(Object value)
{
    throw new NotSupportedException(Environment.GetResourceString("NotSupported_FixedSizeCollection"));
} 
  ...

So you can't do

int[] myArr = { 1, 2 };

myArr.Add(3);

but you can insist on using Add (and get NotSupportedException thrown) via

((IList) myArr).Add(3);

Or even

if (!myArr.IsFixedSize) {
  // we have very strange array, let's try adding a value to it
  ((IList) myArr).Add(3);
}

Why Array does not actually provide Add()?

Array has fixed size, so you cannot add new element(s).

The number of dimensions and the length of each dimension are established when the array instance is created. These values can't be changed during the lifetime of the instance. https://msdn.microsoft.com/en-us/library/9b9dty7d.aspx

Why did it have to implement IList in the first place?

Definition of IList: Represents a non-generic collection of objects that can be individually accessed by index.

https://msdn.microsoft.com/en-us/library/system.collections.ilist.aspx

Array is accessed by index and IList accommodate this index, which is why Array implements IList.

For reference: Why array implements IList?


Though a class implementing an interface must implement all members of the interface, it can implement them explicitly:

public class MyList<T> : IList<T>
{
    // ... shortened for simplicity
    void ICollection<T>.Add(T item) {  } // explicit implementation
}

If you implement the method this way, it won't be visible on instances of MyList<T>:

MyList<int> list = new MyList<int>();
list.Add(5); // would NOT compile
((IList<int>)list).Add(5); // can be compiled

So if you have an int[] you could do that:

int[] array = new int[0];
((IList<int>)array).Add(5);

It will compile, but at runtime a NotSupportedException will be thrown because arrays have fixed size and you cannot add a new element to an array as it's size is determined on initialization (new int[0]).