在上一篇<.NET Framework源码研究系列之---马甲List>中我们一起研究了.NET中 List的源代码,也得到一些兄弟的热心反馈.其中一位仁兄说希望看到ArrayList与LinkedList源 代码,所以今天就以此为话题,大家一起看一下.NET中是如何实现ArrayList和LinkedList 的.
我们先看ArrayList和LinkedList在.NET中的位置,ArrayList的命名空间是 System.Collections,LinkedList的命名空间是System.Collections.Generic,这么看来二者同 属于集合类,只不过LinkedList在一个分支种.然而,稍对.NET的源码分析后,我们会发现二者有 着明显的区别,甚至可以说有质的不同.有这些不同不是因为二者功能的不同,而是微软对它们的 定位不同.在.NET源码物理结构中,ArrayList所在目录 是"redbits\ndp\clr\src\BCL\System\Collections",LinkedList所在目录 是"redbits\ndp\fx\src\CompMod\System\Collections\Generic".由此可知,ArrayList属于CLR 级别的,LinkedList仅仅是额外的扩展.所以说二者其实没有比对的意义.
因为二者没有比较的意义,我们就分成两部分看下二者是如何实现的.先看ArrayList.
public class ArrayList : IList, ICloneable
{
private Object[] _items;
private int _size;
private int _version;
[NonSerialized]
private Object _syncRoot;
private const int _defaultCapacity = 4;
private static readonly Object[] emptyArray = new Object [0];
以上是ArrayList中包含的字段.看过<.NET Framework源码研究系列之---马甲List> 是的兄弟是不是觉得很眼熟呢?
是的,其实ArrayList与List一样.二者同属于CLR基础类,实现过程几乎一模一样.但是二者还 是有细节的不同.
首先,ArrayList是无类型约束的,也就是说ArrayList中可以包含任何类型;而List是强类型 的.虽然二者本质上都是调用 Array的静态方法,如Copy,但在某些方法中ArrayList需要进行装 箱拆箱的操作,由此会带来部分性能损失,如下代码:
public virtual int IndexOf(Object value){
return Array.IndexOf((Array)_items, value, 0, _size);
}
其次,ArrayList继承了ICloneable接口,而List没有.如下.
public virtual Object Clone(){
ArrayList la = new ArrayList(_size);
la._size = _size;
la._version = _version;
Array.Copy(_items, 0, la._items, 0, _size);
return la;
}
由上面代码我们可以看出ArrayList实现的时浅拷贝.这里有个疑惑就是微软对ArrayList实 现克隆接口的初衷,为是浅拷贝而不是深拷贝.