- 没有泛型时的问题
- 用object实现的通用集合类型不安全,无法保证数据元素类型一致
- 值类型会有额外的装箱拆箱开销
- 类型特化的集合每有一个新类型就需要重新实现一遍
- 泛型就是把类型作为参数,从而实现代码重用
- C#的泛型在处理值类型的时候不会有装箱,节省性能和内存
- 省去类型检查的性能开销
- 相同泛型接口的不同构造被视为不同类型,一个类可以多次实现“同一个”泛型接口,虽然不建议,原因不知道没见过这种使用场景
- 构造函数不要求类型参数
- 可以用
xxx = default
提供任意类型的默认值 - 仅类型参数个数不同的“相同”的类,应放到同一个C#文件中
- 嵌套类型自动获得包容类型的类型参数,如果嵌套类型包含自己的类型参数T,会隐藏包容类型的类型参数T
- 泛型约束可以约束基类,接口,类类型约束必须第一个出现,可以约束为Enum,Delegate和MulticastDelegate的子类
- 可以约束为notnull,但不能与struct/class共同使用,因为后两个默认不可空
- 约束为class时可以加个?表示约束为可空类型
- struct不能在约束里写问号,但是可以在T后面写
- new()构造函数约束,要求类型必须具有默认构造函数
- 泛型类型参数和它们的约束不会被派生类继承,泛型类型参数不是成员
- 派生类必须写自己的类型参数,加自己的约束,而且约束的严格性必须等同或更强于基类的约束,然后派生类的类型参数作为基类的类型实参
- 重写虚泛型方法时约束隐式继承且不可以重新声明,额外的约束会破坏多态性,所以不允许新增约束,如果不会新增那自然默认可以继承约束就好了
- 不能在约束之间指定OR关系
泛型方法
- 在泛型类型和非泛型类型中都能声明泛型方法,泛型方法的类型实参可以自动推断,如果推断不准确,可以强转一下参数类型,或者指定类型实参
- 允许使用和泛型类型的类型参数相同的方法指定约束
- 协变逆变见另两篇
- 协变转换的限制
- 只有泛型接口和泛型委托可以协变,泛型类和结构永远不是协变的
- 类型实参必须是引用类型,值类型不允许协变转换,因为值类型没有继承