C#基础加强_泛型的基本原理


 小弟初写博文,深感“易敲千行码,难下百余文”的道理。

内容粗略浅薄,望各位大神海涵!


  • 动态数组ArrayList可以实现不断的增长,让我们感受到了在某些地方较数组有优越感。但它包含的数组类型是object类,意味着需要转为数组时,存在拆装箱操作,这带来不必要的麻烦,也损失了性能。而List<T>泛型集合的出现便大大解决了上述问题。
            //泛型 --泛指某一个类型。这种类型需要用户自己确定
            List<string> lists = new List<string>();
            //添加元素
            lists.Add("aa");
            lists.Add("bb");

            //遍历元素时不用转换类型
foreach (string item in lists) { Console.WriteLine(item); } lists[0] = "abcde"; lists.RemoveAt(0); for (int i = 0; i < lists.Count; i++) { Console.WriteLine(lists[i]); } Console.ReadKey();
  • 泛型集合在创建的时候就要求指定类型,所以在遍历集合或转数组时,直接就是数据的原有类型。其实我们也可以自己写个类似的类实现泛型集合的基本功能。
    //类的参数一般就是指类型参数
    class MyList<T>:
    {
        T[] items=new T[4];
        int count;
        // 集合中元素个数
        public int Count
        {
            get { return count; }
            //set { count = value; }
        } 

        // 添加元素
        public void Add(T value)
        {
            if (this.Count == items.Length)
            {
                T[] newItems = new T[items.Length * 2];
                items.CopyTo(newItems, 0);
                items = newItems;
            }
            items[count] = value;
            count++;
        } 

        // 索引器
        public T this[int index]
        {
            get
            {
                if (index < 0 || index >= this.Count)
                {
                    throw new ArgumentOutOfRangeException("no");
                }
                return items[index];
            }
            set
            {
                if (index < 0 || index >= this.Count)
                {
                    throw new ArgumentOutOfRangeException("no");
                }
                items[index] = value;
            }
        } 
  • 泛型直接通过<T>把元素的类型指定了,添加删除元素和动态数组类似。但是当我们用foreach遍历的时候,出问题了:
错误:“泛型的实现.MyList<int>”不包含“GetEnumerator”的公共定义,
因此 foreach 语句不能作用于“泛型的实现.MyList<int>”类型的变量。
  • 不包含GetEnumerator的公共定义?难道是要实现一个接口?通过反编译器查到 LIST<T>真的实现了名为“IEnumerable”的接口。
   public interface IEnumerable
    {
        [DispId(-4), __DynamicallyInvokable]
        IEnumerator GetEnumerator();
    }
  • 那我们就实现“IEnumerable”这个接口吧,再看IEnumerator,是一个接口对象,原来GetEnumerator()要求返回一个"IEnumerator"的接口对象。纠结了,哪里有这个对象啊。找不到,那我们自己写个类来实现这个接口,不就ok了。
    class MyEnumerator<T> : IEnumerator
    {
        T[] items;         //类型的数组
        int num;           //数组有效长度
        int index = -1;    //迭代指针默认在-1的位置
        //构造函数,
        public MyEnumerator(T[] items, int num)
        {
            this.items = items;
            this.num = num;
        }

        //获取当前元素的值
        public object Current
        {
            get
            {
                return items[index];
            }
        }  

        //先判断有没有下一个元素,如果有就将枚举数推进到下一个元素
        public bool MoveNext()
        {
            index++;
            if (index >= num)
            {
                return false;
            }
            return true;
        } 
        #endregion

        // 迭代重置
        public void Reset()
        {
            index = -1;
        } 
    }
  • 原来IEnumerator接口就是为了实现迭代功能的,foreach遍历的时候并不直接指向第0个元素,就像位置是在-1一样,先来判断有没有第0个元素,没有直接返回false,有则指针移到第0,再执行读取。有了实现IEnumerator的类,就可以new一个MyEnumerator<T>对象来return了。
        //IEnumerable 成员--实现迭代 
        public IEnumerator GetEnumerator()
        {
                //你必须得返回一个实现了IEnumerator接口的类对象
            return new MyEnumerator<T>(items, Count);
        }
  • 现在,MyList<T>也拥有List<T>的基本功能了哦,当然泛型还有很多其他的功能和特性,还有待我们去细细研究了。

 

 

posted on 2014-07-16 22:03  wl-kyo  阅读(1193)  评论(0编辑  收藏  举报

导航