C#.NET里面的数组是怎么实现的?

 

C#.NET里面的数组是怎么实现的?

 

 

探讨数组的实现,List转换为Array的原理。

 

我们应该多用C#里面的数组还是链表呢?Array还是泛型List<T>

 

问题:

 

(1) 由于C#的数组可以通过List转换。当List的长度很大的时候,需要很大的内存,我们相信数组不是一整块内存组成。那么数组必然是由多块内存组成。很自然,可以想到数组是由链表+数组组成。

 

(2) List转换为数组需要花费多少时间?

 

(3) Array是用什么组成的?

 

 

参看MSDN的介绍:

 

看看msdn对数组的定义:

 

(1) C#中,数组实际上是对象,而不只是像 C C++ 中那样的可寻址连续内存区域Array 是所有数组类型的抽象基类型。可以使用 Array 具有的属性以及其他类成员。这种用法的一个示例是使用 Length 属性来获取数组的长度。

 

(2) 数组类型是从抽象基类型 Array 派生的用类型。由于此类型实现了 IEnumerable IEnumerable,因此可以对 C# 中的所有数组使用 foreach 迭代。

 

数组是从Array派生的引用类型。

 

(3) 再看看对Array的介绍

 

Array 类是支持数组的语言实现的基类。但是,只有系统和编译器能够从 Array 类显式派生。用户应当使用由语言提供的数组构造。

 

一个元素就是 Array 中的一个值。Array 的长度是它可包含的元素总数。Array 的秩是 Array 中的维数。Array 中维度的下限是 Array 中该维度的起始索引,多维 Array 的各个维度可以有不同的界限。

 

<shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 7.5pt; HEIGHT: 7.5pt" alt="Note" type="#_x0000_t75"><imagedata o:href="ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.NETDEVFX.v20.chs/cpref2/local/note.gif" src="file:///C:%5CDOCUME~1%5Czhl%5CLOCALS~1%5CTemp%5Cmsohtml1%5C03%5Cclip_image001.gif"></imagedata></shape>重要事项:

 

.NET Framework 2.0 版中,Array 类实现 System.Collections.Generic.IListSystem.Collections.Generic.ICollection System.Collections.Generic.IEnumerable 泛型接口。由于实现是在运行时提供给数组的,因而对于文档生成工具不可见。因此,泛型接口不会出现在 Array 类的声明语法中,也不会有关于只能通过将数组强制转换为泛型接口类型(显式接口实现)才可访问的接口成员的参考主题。将某一数组强制转换为这三种接口之一时需要注意的关键一点是,添加、插入或移除元素的成员会引发 NotSupportedException

 

既然ArraySystem.Collections.Generic.IListSystem.Collections.Generic.ICollection System.Collections.Generic.IEnumerable实现。那么Array就是由链表,集合和枚举器组成的。

 

Array.Copy 方法不仅可在同一类型的数组之间复制元素,而且可在不同类型的标准数组之间复制元素;它会自动处理强制类型转换。

 

(4) ToArray是否耗费更多的时间和空间

 

MSDN:元素使用 System.Array.Copy 来进行复制,后者为一种 O(n) 运算,其中 n Count

 

此方法的运算复杂度为 O(n),其中 n Count

 

这说明ToArray需要额外的内存空间存放新的数组。

 

(5) 是否int[] 可以看成是Array<int>的简写形式?

 

 

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页