问题
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?
回答1:
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
回答2:
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]
回答3:
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.
回答4:
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.
回答5:
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 ;)
来源:https://stackoverflow.com/questions/4482557/what-interfaces-do-all-arrays-implement-in-c