生成模型:DeepSeek-R1,生成时间:2025 03-18 21:17
在 C# 中,泛型(Generic) 是一种让代码可以 复用不同数据类型 技术。它通过占位符 T
(可以是任意标识符)表示类型,在编译时确定具体类型,从而实现类型安全和性能优化。以下是详细解释和示例:
为什么需要泛型?
没有泛型时的问题:假设你想写一个方法交换两个整数,再写另一个方法交换两个字符串,需要重复写大量相似的代码:
// 交换整数
void SwapInt(ref int a, ref int b) { /*...*/ }
// 交换字符串
void SwapString(ref string a, ref string b) { /*...*/ }
泛型的解决方案:只需写一个通用方法,通过 <T>
声明泛型类型:
void Swap<T>(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}
使用时自动推断类型:
int x = 10, y = 20;
Swap(ref x, ref y); // T 被推断为 int
string s1 = "Hello", s2 = "World";
Swap(ref s1, ref s2); // T 被推断为 string
泛型的核心优势
- 类型安全:编译时检查类型错误,避免运行时崩溃。
- 性能优化:避免装箱(Boxing)和拆箱(Unboxing)操作。
- 代码复用:同一套逻辑支持多种数据类型。
泛型的常见用法
1. 泛型方法
// 打印任意类型的数据
void Print<T>(T value)
{
Console.WriteLine($"Value: {value}, Type: {typeof(T)}");
}
Print(100); // Value: 100, Type: System.Int32
Print("Hello"); // Value: Hello, Type: System.String
Print(3.14); // Value: 3.14, Type: System.Double
2. 泛型类
创建一个可以存储任意类型数据的盒子:
public class Box<T>
{
public T Content { get; set; }
public Box(T content)
{
Content = content;
}
}
// 使用示例
Box<int> intBox = new Box<int>(100);
Box<string> strBox = new Box<string>("C#泛型");
Console.WriteLine(intBox.Content); // 100
Console.WriteLine(strBox.Content); // C#泛型
3. 泛型集合(如 List<T>
)
List<int> numbers = new List<int> { 1, 2, 3 };
List<string> names = new List<string> { "Alice", "Bob" };
// 添加元素时类型安全
numbers.Add(4); // 正确
numbers.Add("Five"); // 编译错误!
4. 泛型约束(where)
限制泛型类型必须满足某些条件,例如必须实现接口或具有无参构造函数:
public class Calculator<T> where T : IComparable
{
public T Max(T a, T b)
{
return a.CompareTo(b) > 0 ? a : b;
}
}
// 使用示例
Calculator<int> calc = new Calculator<int>();
Console.WriteLine(calc.Max(10, 20)); // 20
泛型 vs 非泛型对比
场景 | 非泛型(如 ArrayList ) |
泛型(如 List<T> ) |
---|---|---|
添加元素 | 可以添加任意类型(如 list.Add(100) + list.Add("Hello") ) |
只能添加 T 类型(如 list.Add("Hello") ) |
获取元素 | 需要强制类型转换(如 int num = (int)list[0] ) |
直接获取正确类型(如 string s = list[0] ) |
类型错误 | 运行时可能崩溃(如强制转换错误) | 编译时报错 |
性能 | 涉及装箱/拆箱(如 int → object → int ) |
无需装箱拆箱(直接操作原始类型) |
实际应用场景
- 数据容器:如
List<T>
、Dictionary<TKey, TValue>
。 - 工具类:如比较器、排序器。
- 算法复用:如数学计算(最大值、最小值)。
- 接口和委托:如
IEnumerable<T>
、Action<T>
。
总结
泛型是 C# 中实现 类型安全 和 代码复用 的核心技术。通过 <T>
声明占位符类型,再在编译时替换为具体类型,既能避免重复代码,又能提升性能。优先使用泛型集合(如 List<T>
)而非非泛型集合(如 ArrayList
)!