日期:2014-05-17 浏览次数:20975 次
了解了ICollection接口、迭代以及泛型集合,下面再详细了解一下IList接口。
通过MSDN可以看到IList接口有两种:
元素为object类型的IList接口,可以放不同类型的对象引用;
IList<T>泛型接口,只能存放指定类型的对象引用。
其实,IList和IList<T>也称之为向量,特点是可以动态的改变集合的长度,无需确定集合的初始长度,集合会随着存放数据的数量自动变化。
可以看到IList和IList<T>的继承关系:
[ComVisibleAttribute(true)] public interface IList : ICollection, IEnumerable public interface IList<T> : ICollection<T>, IEnumerable<T>, IEnumerable
现在再返回去看下,IList和IList<T>的区别,看如下代码,ArrayList是继承IList的,List继承IList<T>:
public class IListClass { void test() { TestClass1 c1 = null; ArrayList arryList = new ArrayList(); arryList.Add(c1); List<TestClass1> list = new List<TestClass1>(); list.Add(c1); //取值 TestClass1 getC1Array = arryList[0] as TestClass1;//必须要一次强制转换 TestClass1 getC1List = list[0];//不需要转换,所谓泛型 } } public class TestClass1 { }
这下就比较明白了。
一、IList接口概述
ILis接口从ICollection接口继承,具备以下特性,
Count属性——获取集合元素个数;
GetEnumerator方法——可以迭代;
CopyTo方法——将指定元素复制到另一个数组中;
Clear方法——清空整个集合。
IList新增特性,
索引器属性——根据索引访问集合中任意元素;
Add方法——向集合末尾添加元素;
Insert方法——向集合指定位置插入元素;
Remove方法——移除指定元素;(包括RemoveAt)
Contains方法——判断对象是否在集合中;
IndexOf方法——查找指定对象在集合中的索引位置。
另外,IList接口集合按照顺序存放元素,不改变元素存放顺序。
2、算法
向量集合和数组一样,具备随即访问的特点。即无论访问向量集合的任何一个单元,所需的访问时间是完全相同的。在向量类中,实际上依然使用普通数组来记录集合数据,向量类使用了一些算法技巧,让整个类对外表现不同于普通数组的重要特点:可以动态改变数组长度。具体算法如下:
在内部数组足够长的情况下,直接进行添加和插入操作,在内部数组长度不足的情况下,按照内部数组长度增加2倍作为新的数组的长度,然后进行数据搬移(即把就数组数组移到新数组中)。向量在分配元素存储空间时,会多分配一些冗余空间,尽量减少内存分配次数。在数据删除时,并不改变内部数组长度,仅仅是使用被删除数据之后的数据覆盖被删除的数据。
不过向量每次分配空间时都多分配一些冗余空间,会造成内存的压力,因此在程序中应该尽量避免集中的次数繁多的内存分配。
三、实现类
IList和IList<T>的实现类,分别是ArrayList类和List<T>类。
ArrayList类处于System.Collection命名空间下;
List<T>类处于System.Collection.Specialized命名空间下。
四、实现代码(非泛型)
/// <summary> /// 实现IList,非泛型 /// </summary> public class ArrayList : IList { /// <summary> /// 迭代 /// </summary> public struct Enumertor : IEnumerator { /// <summary> /// 迭代索引 /// </summary> private int index; /// <summary> /// 迭代器所属的向量类对象的引用 /// </summary> private ArrayList arrayList; /// <summary> /// 构造函数 /// </summary> /// <param name="arrayList">迭代器所属的集合类</param> public Enumertor(ArrayList arrayList) { this.arrayList = arrayList; this.index = -1; } /// <summary> /// 获取当前对象,根据index的值返回向量对应的对象引用 /// </summary> public object Current { get { return arrayList[index]; } } /// <summary> /// 将迭代器指向下一个数据位置,通过改变index的值,加1或减1 /// </summary> /// <returns></returns> public bool MoveNext() { if (this.index < arrayList.Count) { ++this.index; } return this.index < arrayList.Count; } /// <summary> /// 迭代器回到起始位置,将index置为-1 /// </summary> public void Reset() { this.index = -1; }