在C#中,泛型是一种把类型参数化的机制,它允许我们在定义类、方法、接口或委托时不指定具体的数据类型,而是在调用时再确定。这样可以写出更通用、复用性更高的代码,同时保留编译期的类型安全检查。

什么是C#泛型
传统的写法如果要处理不同类型,往往使用object类型,但会带来装箱拆箱和类型转换风险。泛型通过类型参数(通常用T表示)解决这个问题。例如List<string>中的string就是实际传入的类型参数。
泛型的基本形式
泛型类或方法在名称后面用尖括号包裹类型参数:
// 定义一个简单的泛型类
public class Box<T>
{
private T item;
public void Set(T value) { item = value; }
public T Get() { return item; }
}
// 使用泛型类
Box<int> intBox = new Box<int>();
intBox.Set(10);
int num = intBox.Get();
如何使用泛型方法
除了泛型类,我们也可以定义泛型方法,它能在普通类中独立使用类型参数。
示例:交换两个变量
public static void Swap<T>(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}
int x = 1, y = 2;
Swap<int>(ref x, ref y);
// 此时 x=2, y=1
泛型约束
有时我们希望类型参数必须满足某些条件,比如必须是引用类型或实现了某个接口,这时可以用where关键字添加约束。
| 约束形式 | 含义 |
|---|---|
| where T : class | T必须是引用类型 |
| where T : struct | T必须是值类型 |
| where T : IComparable | T必须实现IComparable接口 |
带约束的泛型方法
// 要求T必须是值类型
public static T Max<T>(T a, T b) where T : struct, IComparable<T>
{
return a.CompareTo(b) >= 0 ? a : b;
}
int m = Max<int>(3, 5); // 返回5
常见使用场景
- 集合类:如List<T>、Dictionary<TKey, TValue>
- 工具方法:如上面提到的Swap、Max
- 仓储层或业务逻辑中需要通用处理的实体类
泛型不是黑魔法,本质是在编译时由编译器帮我们生成具体类型的版本,所以既安全又高效。
小结
理解C#泛型只需要记住一点:它让类型成为参数。从泛型集合入手,再尝试写自己的泛型方法和带约束的泛型类,就能慢慢掌握这套非常实用的语言特性。