泛型
Posted Chris_在IT道路上前行
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了泛型相关的知识,希望对你有一定的参考价值。
泛型(generic)是CLR和编程语言提供的一种特殊机制,它支持另一种形式的代码重用,即算法重用。
简单的说,开发人员先定义好一个算法,比如排序、搜索、交换、比较或者转换等。但是,定义算法的开发人员并不设定该算法要操作什么数据类型。该算法可以广泛地应用于不同类型的对象。然后,另一个开发人员,只有指定了算法要操作的具体数据类型,就可以开始使用这个现成的算法了。例如,可以用一个排序算法来操作Int32和String等类型对象。
大多数算法都封装在一个类型中,CLR允许创建泛型引用类型和泛型值类型,但不允许创建泛型枚举类型。CLR还允许创建泛型接口和泛型委托。
先来看一个简单的例子,Framework类库中定义了一个泛型列表算法,它知道如何管理一个对象集合。泛型算法没有设定这些对象的数据类型。
封装了泛型列表算法的FCL类称为List<T>。泛型List类的设计者紧接着在这个类名后添加一个<T>,表明它操作的是一个未指定的数据类型。
定义泛型类型时,它为类型指定的任何变量(比如T)都称为类型参数(type parameter)。T是一个变量名,在源代码中能够使用一个数据类型的任何位置,都能使用T。
列如:在List类定义中,
T被用作方法参数,Add方法接收一个T类型的参数public void Add(T item);
T被用作返回值,ToArray方法返回一组T类型的一维数组public T[] ToArray();
根据Microsoft的设计原则,泛型参数变量要么称为T,要么至少以大写T开头(如TKey和TValue)。
使用泛型类型或方法时,指定的具体数据类型称为类型实参(type argument)。
例如:开发人员可指定一个DateTime类型实参来使用List算法。
public class Program{
private static void SomeMethod()
{
//构造一个List来操作DateTime对象
List<DateTime> dtList = new List<DateTime>();
//向列表添加DateTime对象,不进行装箱
dtList.Add(DateTime.Now);
dtList.Add(DateTime.MinValue);
//尝试向列表中添加一个String对象,编译时报错,Invalid arguments
dtList.Add("1/1/2004");
//从列表提取一个DateTime对象
DateTime dt = dtList[0];
}
}
从以上代码可以看出,泛型为开发人员提供了以下优势:
- 源代码保护à使用一个泛型算法的开发人员不需要访问算法的源代码
- 类型安全à保证只有与指定具体数据类型兼容的对象才能随同算法使用
- 更加清晰的代码à DateTime dt = dtList[0];中不需要使用(DateTime)转型将索引器的结果存储在dt变量中
- 更佳的性能à现在能创建一个泛型算法来操作具体的数据类型,所有值类型的实例都能以传值方式传递,CLR不再需要执行任何装箱操作
12.1 Framework类库中的泛型
泛型最明显的应用就是集合类。
FCL定义的几个泛型集合类,大多数都在System.Collections.Generic和System.Collections.ObjectModel命名空间中。
12.2Wintellect的Power Collections库
12.3泛型基础结构
泛型是在CLR2.0版本中加入的,为了在CLR中加入泛型,Microsoft做了一下工作:
- 创建新的IL指令,使之能够识别类型实参。
- 修改现有元数据表的格式,以便表示具有泛型参数的类型名称和方法。
- 修改各种编程语言,以支持新的语法,允许开发人员定义和引用泛型类型和方法。
- 修改编译器,使之能生成新的IL指令和修改的元数据格式。
- 修改JIT编译器,使之能处理新的、支持类型实参的IL指令,以便生成正确的本地代码。
- 创建新的反射成员,是开发人员能查询类型和成员,以判断它们是否具有泛型参数。
- 修改调试显示器以显示和修改泛型类型、成员、字段以及局部变量。
- 修改Visual Studio的智能感知“IntelliSense”。
12.3.1开放类型和封闭成员
以上是关于泛型的主要内容,如果未能解决你的问题,请参考以下文章