.net集合类的研究--Array,ArrayList,List<T>

最近研究Nhibernate,看着样例代码一知半解,苦恼万分,发现中间又引用了一个Iesi.Collections,不禁要产生疑问--为什么要专门引用一个集合类程序集?这个程序集里的集合数组类与.net自带的有什么不一样?结果此问题一出就一发不可收拾,扪心自问冒出了一大堆的问题--.net有哪些集合类?array和ArrayList有什么区别?Hashtable与集合有什么不一样?....等等.这时才意识到,如果对.net本身提供的集合类不了解,根本不会明白引用Iesi.Collections的用意.

由<<CLR via C#>>的书中所说:"所有的数组(如int[],FileStream[],object[])都隐式派生自System.Array,所有数组都隐式实现IEnumerable,ICollection,IList",所以先从Array开始研究,用Reflector工具找到Array源代码,发现除去一堆的静态方法如Sort,Find,BinarySearch以外,几乎就不剩什么东西了.

其中比较重要的一点是Array仅仅用显示接口实现了一个私有IList.Add方法,这意味着:Array实例没有办法调用Add方法,一旦初始化以后,长度不可变.

int IList.Add(object value)
{
throw new NotSupportedException(Environment.GetResourceString("NotSupported_FixedSizeCollection"));
}

同样通过源代码可以看到ArrayList和Array的区别,ArrayList内置了一个Array变量 _items(代码中红色标出),

也就是说:ArrayList是Array的一层封装,实际数据操作还是针对Array.

 
  
[Serializable, ComVisible( true ), DebuggerDisplay( " Count = {Count} " ), DebuggerTypeProxy( typeof (ArrayListDebugView))]
public class ArrayList : IList, ICollection, IEnumerable, ICloneable
{
// Fields
private const int _defaultCapacity = 4 ;
private object [] _items;
private int _size;
// Methods
  ...........
}

ArrayList有Add方法,当Add方法发现内部的object[]容量已满时,便会调用一个方法自动扩充object[]容量,既然ArrayList的实质是操作object[],而Array长度不可变,那么如何扩充?其实说白了,就是通过调用EnsureCapacity方法再创建一个更长的object[]数组,然后把原数组复制到新的数组中.

ArrayList的很多方法如Sort,Indexof,内部都是调用了Array的静态方法,如IndexOf方法:

 
  
public virtual int IndexOf( object value)
{
return Array.IndexOf( this ._items, value, 0 , this ._size);
}

.net2.0以后出现了泛型,目的是为了避免装箱拆箱操作造成的性能损失.ArrayList对应的泛型集合就是List<T>.

由于泛型的出现,List<T>内部操作的不再是object[],而是T[],提供的很多方法如Sort,IndexOf等,同ArrayList类一样,内部也是调用Array的静态方法来操作数组.

因为Array的局限性,List<T>的一些方法会用到循环,如Find方法:

 
  
public T Find(Predicate < T > match)
{
if (match == null )
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
for ( int i = 0 ; i < this ._size; i ++ )
{
if (match( this ._items[i]))
{
return this ._items[i];
}
}
return default (T);
}

其中Predicate<T>是一个委托,在.net内部定义,需要一个类型为T的参数,返回值为bool.

知道这些可以避免我们把这些方法用在自己写的循环中,造成性能损失.


Array,ArrayList和List<T>在使用上如何选择呢?由于泛型可以避免装箱拆卸的性能损失,2.0以后的泛型集合基本上能淘汰以前的非泛型集合,所以ArrayList不做考虑,只比较Array和List<T>.

标准答案:确定了Array大小的时候,选用Array,不确定大小时,使用List<T>.

个人观点:如果数组是1维的,使用List<T>和Array之间的性能损失微乎其微,而List<T>可以带来更大的灵活性,因为很多时候想法和业务逻辑是多变的,建议多用List<T>.

刚写完后,查了博客园,发现这个问题在园子里已经被说的很透彻了,给出链接重新理解List<T>.

转载于:https://www.cnblogs.com/hkncd/archive/2011/05/02/2034641.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值