《Illustrated C# 2012, 4th Edition》Daniel M. Solis 第17章 泛型 笔记

泛型(generic)是C# 2.0引入的。
泛型允许我们声明类型参数化(type-parameterized)的代码。
泛型不是类型,是类型的模板。
C#提供5种泛型:类、结构、接口、委托、方法。

泛型声明中的T是占位符,在编译时替换为实际类型,其中T称为类型参数(type parameter),实际类型称为类型实参(type argument)。

将泛型类型中的占位符替换为实际类型后,得到的类型称为构造类型(constructed type)。

类型参数可以受约束(constrain),符合约束的类型参数称为未绑定的类型参数(unbounded type parameter)。
泛型中,约束通过where子句给出:

where TypeParam : constraint, constraint, ....

约束有5种类型:

如果同时存在多种约束,必须按以下形式给出:

泛型方法可以在泛型或非泛型的类型中声明。
泛型方法调用时,编译器可以推断实际类型,因此在调用时,可以省略类型参数和尖括号。
扩展方法支持泛型。

非泛型类型可以实现泛型接口。
一个类型可以重复实现相同的泛型接口,但泛型接口的类型实参必须不存在相同类型的可能性。

泛型可以与非泛型重名。

可变性(variance)分为三种:协变(convariance)、逆变(contravariance)和不变(invariance)。
当泛型委托的类型形参使用out修饰,表示这个类型形参只作为返回值类型,则这个泛型委托支持协变,即支持将类型实参为派生类的委托对象赋值给类型实参为基类的委托对象。
当泛型委托的类型形参使用in修饰,表示这个类型形参只作为形参类型,则这个泛型委托支持逆变,即支持将类型实参为基类的委托对象赋值给类型实参为派生类的委托对象。
与泛型委托相同,泛型接口也通过out和in修饰符支持协变和逆变。
不使用out和in修饰的类型参数称为不变,不支持协变和逆变。

当赋值运算符左操作数为泛型委托,右操作数为函数时,不需要out和in修饰符,只要类型形参满足协变和逆变的条件(协变:只作为返回值类型。逆变:只作为形参类型。),就支持协变和逆变: