1.泛型概述
泛型广泛用于容器(collections);
命名空间System.Collections.Generic ;
2.泛型优点
以前类型的泛化(generalization)是靠类型与全局基类
System.Object的相互转换来实现。.NET框架基础类库的ArrayList容器类,就是这种局限的一个例子。
ArrayList是一个很方便的容器类,使用中无需更改就可以存储任何引用类型或值类型;
3.泛型类型参数
在泛型类型或泛型方法的定义中,类型参数是一个占位符(placeholder),通常为一个大写字母,如T。
在客户代码声明、实例化该类型的变量时,把T替换为客户代码所指定的数据类型。
泛型类,如泛型概述中给出的MyList<T>类,不能用作as-is,原因在于它不是一个真正的类型,而更像是一个类型的蓝图。
要使用MyList<T>,客户代码必须在尖括号内指定一个类型参数,来声明并实例化一个已构造类型(constructed type)。
这个特定类的类型参数可以是编译器识别的任何类型;
4.类型参数的约束
若要检查表中的一个元素,以确定它是否合法或是否可以与其他元素相比较,那么编译器必须保证:客户代码中可能出现的所有类型参数,都要支持所需调用的操作或方法。
这种保证是通过在泛型类的定义中,应用一个或多个约束而得到的。
一个约束类型是一种基类约束,它通知编译器,只有这个类型的对象或从这个类型派生的对象,可被用作类型参数。
一旦编译器得到这样的保证,它就允许在泛型类中调用这个类型的方法;
5.泛型类
泛型类封装了不针对任何特定数据类型的操作。
泛型类常用于容器类,如链表、哈希表、栈、队列、树等等。
这些类中的操作,如对容器添加、删除元素,不论所存储的数据是何种类型,都执行几乎同样的操 作
6.泛型接口
不论是为泛型容器类,还是表示容器中元素的泛型类,定义接口是很有用的。
把泛型接口与泛型类结合使用是更好的用法,比如用IComparable<T>而非IComparable,以避免值 类型上的装箱和拆箱操作。
.NET框架2.0类库定义了几个新的泛型接口,以配合System.Collections.Generic中新容器类的使用
7.泛型委托
论是在类定义内还是类定义外,委托可以定义自己的类型参数。
引用泛型委托的代码可以指定类型参数来创建一个封闭构造类型,这和实例化泛型类或调用泛型方 法一样
8.泛型代码中的default 关键字
在泛型类和泛型方法中会出现的一个问题是,如何把缺省值赋给参数化类型,此时无法预先知道以下两点:
T将是值类型还是引用类型
如果T是值类型,那么T将是数值还是结构对于一个参数化类型T的变量t,仅当T是引用类型时,t = null语句才 是合法的; t = 0只对数值的有效,而对结构则不行。
这个问题的解决办法是用default关键字,它对引用类型返回空,对值类型的数值型返回零。
而对于结构,它将返回结构每个成员,并根据成员是值类型还是引用类型,返回零或空
9.C++ 模板和C# 泛型的区别
泛型和c++模板都是为参数化类型提供支持的语言特性。
然而,两者之间有许多不同之处。
在语法级别,c#泛型是一种更简单的参数化类型方法,没有c++模板的复杂性。
此外,c#不尝试提供c++模板提供的所有功能。
在实现级别,主要的区别是c#泛型类型替换是在运行时执行的,因此为实例化的对象保留了泛型类 型信息.
10.运行时的泛型
当泛型类或泛型方法被编译为微软中间语言(MSIL)后,它所包含的元数据定义了它的类型参数。
根据所给的类型参数是值类型还是引用类型,对泛型类型所用的MSIL也是不同的。
当第一次以值类型作为参数来构造一个泛型类型,运行时用所提供的参数或在MSIL中适当位置被替换的参数,来创建一个专用的泛型类型;
11.基础类库中的泛型