首页 > 代码库 > 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>的基本功能了哦,当然泛型还有很多其他的功能和特性,还有待我们去细细研究了。
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。