日期:2014-05-17  浏览次数:20975 次

C#基础知识整理 基础知识(16) IList接口——非泛型

了解了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;
            }