首页 > 代码库 > C#基础加强_泛型的基本原理

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>的基本功能了哦,当然泛型还有很多其他的功能和特性,还有待我们去细细研究了。