小弟初写博文,深感“易敲千行码,难下百余文”的道理。
内容粗略浅薄,望各位大神海涵!
- 动态数组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>的基本功能了哦,当然泛型还有很多其他的功能和特性,还有待我们去细细研究了。