C# 中的泛型:为何需要及如何使用
\n\n在使用 C# 进行开发时,每个人迟早都会遇到这样的情况:需要对不同的数据类型应用相同的算法。过去,要么必须为一个方法编写多个版本,要么使用 object 类型,但这会导致性能损失和出错风险。这个问题的解决方案就是 泛型。在本文中,我们将详细讲解什么是泛型、为什么需要它们以及如何在 C# 中正确使用它们。
什么是 C# 中的泛型?
\n\n泛型是 C# 语言的一种机制,它允许创建能够处理不同数据类型、同时保持强类型特性的类、方法、接口和委托。您无需为每种类型单独编写代码,而是创建一个通用模板,在编译时替换为所需的类型。
\n\n想象一下,您需要编写一个交换两个变量值的方法。没有泛型,您必须为 int、string、double 等类型分别创建单独的方法。而使用泛型,您只需编写一个适用于任何类型的方法。
下面是一个声明泛型方法的最简单示例:
\n\npublic void Swap<T>(ref T a, ref T b)\n{\n T temp = a;\n a = b;\n b = temp;\n}\n\n这里的 <T> 是类型参数。字母 T 是通用约定(来自 Type),但您可以使用任何名称。当您调用该方法时,需要指定具体的类型:
int x = 5, y = 10;\nSwap<int>(ref x, ref y);\n// 现在 x = 10, y = 5\n\nstring first = "Hello", second = "World";\nSwap<string>(ref first, ref second);\n// 现在 first = "World", second = "Hello"\n\n为什么需要泛型:主要优势
\n\n使用泛型带来了几个重要的优势,使代码更优秀、更安全。
\n\n1. 类型安全
\n与使用 object 不同,泛型在编译阶段就进行类型检查。您无法意外地将字符串传递给期望数字的地方。编译器会立即指出错误。
2. 性能
\n使用 object 时,值类型(int、double、struct)会进行装箱(boxing)转换为引用类型,以及反向拆箱(unboxing)操作。这些都是开销很大的操作。泛型完全消除了这些过程,因为编译器会为每种类型生成专门的代码。
3. 代码复用
\n您无需为不同类型编写相同的算法。一个泛型类或方法可以处理成千上万种不同的类型。
\n\n4. 可读性和可维护性
\n代码变得更清晰、更易理解。您可以明确看到方法或类处理的是哪些类型,而逻辑与具体数据类型分离。
\n\n如何使用泛型:实际示例
\n\n让我们来看几个在 C# 中使用泛型的实际场景。
\n\n泛型类
\n最常见的例子是集合。您无需创建自己的类来存储数字、字符串或自定义对象的列表,而是使用 List<T>:
List<int> numbers = new List<int>();\nnumbers.Add(1);\nnumbers.Add(2);\n\nList<string> names = new List<string>();\nnames.Add("Alice");\nnames.Add("Bob");\n\n// 您自己的泛型类\npublic class Repository<T>\n{\n private List<T> _items = new List<T>();\n\n public void Add(T item) => _items.Add(item);\n public T Get(int index) => _items[index];\n}\n\nRepository<int> intRepo = new Repository<int>();\nintRepo.Add(100);\nint value = intRepo.Get(0); // 100\n\n泛型方法
\n即使在普通类内部,方法也可以是泛型的:
\n