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?
From the documentation (emphasis mine):
[...] the Array class implements the
System.Collections.Generic.IList<T>
,System.Collections.Generic.ICollection<T>
, andSystem.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
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]
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.
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.
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...
After that i got only one - there_is_no_array ;)
来源:https://stackoverflow.com/questions/4482557/what-interfaces-do-all-arrays-implement-in-c