C# 泛型是一种强大的编程特性,允许开发者编写可重用、类型安全且高效的代码。通过泛型,可以在定义类、接口、方法或委托时使用类型参数,实际使用时再指定具体类型。以下是关于 C# 泛型的详细介绍:
泛型的核心优势
类型安全
泛型在编译时检查类型,避免运行时类型转换错误(如 object
的装箱拆箱操作)。
代码复用
同一套逻辑可适用于多种数据类型,无需为不同类型重复编写代码。
性能优化
避免值类型的装箱拆箱操作,提升性能(例如使用 List<int>
而非 ArrayList
)。
泛型的基本用法
泛型类(Generic Class)
|
|
泛型接口(Generic Interface)
|
|
泛型方法(Generic Method)
|
|
泛型委托(Generic Delegate)
|
|
类型约束(Type Constraints)
通过 where
关键字限制泛型参数的类型范围,增强类型安全性。
约束类型 | 示例 | 说明 |
---|---|---|
值类型 | where T : struct | T 必须是值类型(如 int ) |
引用类型 | where T : class | T 必须是引用类型(如 string ) |
无参构造函数 | where T : new() | T 必须有默认构造函数 |
基类约束 | where T : SomeBaseClass | T 必须继承自指定基类 |
接口约束 | where T : ISomeInterface | T 必须实现指定接口 |
组合约束 | where T : class, new() | 多条件约束 |
示例:
|
|
协变与逆变(Covariance & Contravariance)
允许在泛型类型中更灵活地处理继承关系,通过 out
(协变)和 in
(逆变)关键字实现。
协变(Covariance)
- 用于返回值类型(
out T
)。 - 允许将派生类型作为泛型参数传递给接受基类型的接口。
|
|
逆变(Contravariance)
- 用于参数类型(
in T
)。 - 允许将基类型作为泛型参数传递给接受派生类型的接口。
|
|
泛型中的默认值
使用 default(T)
获取类型的默认值:
- 引用类型:
null
- 值类型:0、
false
等。
|
|
泛型与集合
.NET 提供了丰富的泛型集合类,如:
List<T>
:动态数组Dictionary<TKey, TValue>
:键值对Queue<T>
:先进先出队列Stack<T>
:后进先出栈
对比非泛型集合(如 ArrayList
):
- 泛型集合无需类型转换,直接操作具体类型。
- 避免因错误类型导致的运行时异常。
高级主题
反射与泛型
通过反射动态创建泛型类型或方法:
|
|
泛型类型推断
编译器根据参数自动推断类型:
|
|
静态成员行为
每个封闭泛型类型(如 MyClass<int>
和 MyClass<string>
)拥有独立的静态成员。
使用场景
- 需要处理多种数据类型的通用算法(如排序、搜索)。
- 构建可复用的库或框架(如 ORM 中的泛型 Repository)。
- 实现设计模式(工厂模式、策略模式等)。
总结
C# 泛型通过类型参数化显著提升了代码的灵活性和安全性,是编写高效、可维护代码的重要工具。合理使用泛型约束、协变/逆变等特性,可以进一步优化设计,减少重复代码。