What interfaces do all arrays implement in C#?

匿名 (未验证) 提交于 2019-12-03 01:55:01

问题:

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 (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.

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, System.Collections.Generic.ICollection, and System.Collections.Generic.IEnumerable 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 )



回答3:

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

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;         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.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!