What interfaces do all arrays implement in C#?

C#.NetArraysInterface Implementation

C# Problem Overview


As a new .NET 3.5 programmer, I started to learn LINQ and I found something pretty basic that I haven't noticed before:

The book claims every array implements IEnumerable<T> (obviously, otherwise we couldn't use LINQ to objects on arrays...). When I saw this, I thought to myself that I never really thought about that, and I asked myself what else all arrays implement - so I examined System.Array using the object browser (since it's the base class for every array in the CLR) and, to my surprise, it doesn't implement IEnumerable<T>.

So my question is: where is the definition? I mean, how can I tell exactly which interfaces every array implements?

C# Solutions


Solution 1 - C#

From the documentation (emphasis mine):

> [...] the Array class implements the System.Collections.Generic.IList<T>, System.Collections.Generic.ICollection<T>, and System.Collections.Generic.IEnumerable<T> generic interfaces. The implementations are provided to arrays at run time, and therefore are not visible to the documentation build tools.

EDIT: as Jb Evain points out in his comment, only vectors (one-dimensional arrays) implement the generic interfaces. As to why multi-dimensional arrays don't implement the generic interfaces, I'm not quite sure since they do implement the non-generic counterparts (see the class declaration below).

The System.Array class (i.e. every array) also implements these non-generic interfaces:

public abstract class Array : ICloneable, IList, ICollection, IEnumerable, IStructuralComparable, IStructuralEquatable

Solution 2 - C#

You can find the answer to your question empirically using a small code snippet:

foreach (var type in (new int[0]).GetType().GetInterfaces())
    Console.WriteLine(type);

Running the above snippet would result in the following output (on .NET 4.0):

System.ICloneable
System.Collections.IList
System.Collections.ICollection
System.Collections.IEnumerable
System.Collections.IStructuralComparable
System.Collections.IStructuralEquatable
System.Collections.Generic.IList`1[System.Int32]
System.Collections.Generic.ICollection`1[System.Int32]
System.Collections.Generic.IEnumerable`1[System.Int32]

(`1 means <T>)

After .NET 4.5 (.NET Standard 1.0 and later), there's two additional interfaces:

System.Collections.Generic.IReadOnlyList`1[System.Int32]
System.Collections.Generic.IReadOnlyCollection`1[System.Int32]

Solution 3 - C#

Starting with .NET 4.5, arrays also implement the interfaces System.Collections.Generic.IReadOnlyList<T> and System.Collections.Generic.IReadOnlyCollection<T>.

Thus, when using .NET 4.5, the complete list of interfaces implemented by arrays becomes (obtained using the method presented in Hosam Aly's answer):

System.Collections.IList
System.Collections.ICollection
System.Collections.IEnumerable
System.Collections.IStructuralComparable
System.Collections.IStructuralEquatable
System.Collections.Generic.IList`1[System.Int32]
System.Collections.Generic.ICollection`1[System.Int32]
System.Collections.Generic.IEnumerable`1[System.Int32]
System.Collections.Generic.IReadOnlyList`1[System.Int32]
System.Collections.Generic.IReadOnlyCollection`1[System.Int32]

Strangely, it seems that it was forgotten to update the documentation on MSDN to mention these two interfaces.

Solution 4 - C#

Carefully on array interfaces, they may implement them but actually they don't really do this... Take a loon on the following code:

            var x = new int[] { 1, 2, 3, 4, 5 };
        var y = x as IList<int>;
        Console.WriteLine("The IList:" + string.Join(",", y));
        try
        {
            y.RemoveAt(1);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
        Console.WriteLine(string.Join(",", y));

It produces the following output: result

So parsing works but not everything is supported which is correct from fixed length collection perspective but quite wrong if you really believe that it is a list. There goes Liskov principle from SOLID :(.

For testing fast this will help.

Solution 5 - C#

I have found the implementation of the IList<T>, ICollection<T>, IEnumerable<T> in the SZArrayHelper nested class of the Array.

But i have to warn you - there you will find much more questions...

The refference

After that i got only one - there_is_no_array ;)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionET.View Question on Stackoverflow
Solution 1 - C#BoltClockView Answer on Stackoverflow
Solution 2 - C#Hosam AlyView Answer on Stackoverflow
Solution 3 - C#cr7pt0gr4ph7View Answer on Stackoverflow
Solution 4 - C#Adrian P.View Answer on Stackoverflow
Solution 5 - C#KamertonView Answer on Stackoverflow