泛型基础
泛型是CLR和编程语言提供的一种特殊机制,它可以支持代码重用。
我们在编写程序的时候,经常会遇到两个模块的功能非常相似,只是一个处理int类型的数据一个处理string数据,或者其他自定义的数据类型,而c#中的类型是强类型,我们不得不写多个方法分别处理不同的带护具类型,那么有没有一种办法,在方法中传入通用的数据类型,这样只要实现一个方法就可以了?泛型这种机制就是为了就是这个问题的解决方案之一。
例如我们要实现一个栈:
public class Stack { private List<Int32> m_item; public Int32 Pop(){ if (m_item.Count < 1) { throw new NullReferenceException(); } else { Int32 popValue = m_item[m_item.Count - 1]; m_item.RemoveAt(m_item.Count - 1); return popValue; } } public void Push(Int32 item) { m_item.Add(item); } public Stack(Int32 i) { this.m_item = new List<Int32>(); } }
上面的代码运行没有任何问题,但是他只能处理Int类型的栈结构,如果需要一个浮点数或者字符串型的栈就需要重新实现一遍栈。我们雍凡星来重新实现一次栈如下:
public class Stack<T> { private List<T> m_item; public T Pop() { if (m_item.Count < 1) { throw new NullReferenceException(); } else { T popValue = m_item[m_item.Count - 1]; m_item.RemoveAt(m_item.Count - 1); return popValue; } } public void Push(T item) { m_item.Add(item); } public Stack() { this.m_item = new List<T>(); } }
以上,T只是一个占位符,它可以是任意的值类型或者引用类型,枚举类型除外,这样一个方法就可以支持int类型的栈结构也可以支持double类型的栈;调用如下:
Stack<Int32> stack = new Stack<Int32>(); stack.Push(1); stack.Push(100); Int32 value = stack.Pop();
泛型的好处:
- 它是类型安全的。实例化了int类型的栈,就不能处理string类型的数据,其他数据类型也一样。
- 无需装箱和折箱。这个类在实例化时,按照所传入的数据类型生成本地代码,本地代码数据类型已确定,所以无需装箱和折箱。
- 无需类型转换。
泛型类在编译时,先生成中间代码IL,通用类型T只是一个占位符。在实例化类时,根据用户指定的数据类型代替T并由即时编译器(JIT)生成本地代码,这个本地代码中已经使用了实际的数据类型,等同于用实际类型写的类,所以不同的封闭类的本地代码是不一样的。按照这个原理,我们可以这样认为:
泛型类的不同的封闭类是分别不同的数据类型。
例:Stack<int>和Stack<string>是两个完全没有任何关系的类,你可以把他看成类A和类B,这个解释对泛型类的静态成员的理解有很大帮助。
一些典型的泛型类
Net框架类库中,System.Collections.Generic和System.Collections.ObjectModel命名空间中,分别定义了大量的泛型类和泛型接口,这些泛型类多为集合类,因为泛型最大的应用正体现于再集合中对于不同类型对象的管理。
下表列出了,.Net框架中常用的泛型类和泛型接口:
泛型类 |
说明 |
List<T> |
对应于ArrayList集合类,可以动态调整集合容量,通过索引方式访问对象,支持排序、搜索和其他常见操作。 |
SortedList<TKey,TValue> |
对应于SortedList集合类,表示Key/Value对集合,类似于SortedDictionary<TKey,TValue>集合类,而SortedList在内存上更有优势。 |
Queue<T> |
对应于Queue集合类,是一种先进先出的集合类,常应用于顺序存储处理。 |
Stack<T> |
对应于Stack集合类,是一种后进先出的集合类。 |
Collection<T> |
对应于CollectionBase集合类,是用于自定义泛型集合的基类,提供了受保护的方法来实现定制泛型集合的行为Collection<T>的实例是可修改的。 |
Dictionary<TKey,TValue> |
对应于Hashtable集合类,表示Key/Value对的集合类,Key必须是唯一的,其元素类型既不是Key的类型,也不是Value的类型,而是KeyValuePair类型。 |