泛型是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类型。 |