C# 中的泛型:初学者指南——为何需要及如何使用

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

C# 中的泛型:为何需要及如何使用

\n\n

在使用 C# 进行开发时,每个人迟早都会遇到这样的情况:需要对不同的数据类型应用相同的算法。过去,要么必须为一个方法编写多个版本,要么使用 object 类型,但这会导致性能损失和出错风险。这个问题的解决方案就是 泛型。在本文中,我们将详细讲解什么是泛型、为什么需要它们以及如何在 C# 中正确使用它们。

\n\n

什么是 C# 中的泛型?

\n\n

泛型是 C# 语言的一种机制,它允许创建能够处理不同数据类型、同时保持强类型特性的类、方法、接口和委托。您无需为每种类型单独编写代码,而是创建一个通用模板,在编译时替换为所需的类型。

\n\n

想象一下,您需要编写一个交换两个变量值的方法。没有泛型,您必须为 int、string、double 等类型分别创建单独的方法。而使用泛型,您只需编写一个适用于任何类型的方法。

\n\n

下面是一个声明泛型方法的最简单示例:

\n\n
public 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),但您可以使用任何名称。当您调用该方法时,需要指定具体的类型:

\n\n
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\n

1. 类型安全

\n

与使用 object 不同,泛型在编译阶段就进行类型检查。您无法意外地将字符串传递给期望数字的地方。编译器会立即指出错误。

\n\n

2. 性能

\n

使用 object 时,值类型(int、double、struct)会进行装箱(boxing)转换为引用类型,以及反向拆箱(unboxing)操作。这些都是开销很大的操作。泛型完全消除了这些过程,因为编译器会为每种类型生成专门的代码。

\n\n

3. 代码复用

\n

您无需为不同类型编写相同的算法。一个泛型类或方法可以处理成千上万种不同的类型。

\n\n

4. 可读性和可维护性

\n

代码变得更清晰、更易理解。您可以明确看到方法或类处理的是哪些类型,而逻辑与具体数据类型分离。

\n\n

如何使用泛型:实际示例

\n\n

让我们来看几个在 C# 中使用泛型的实际场景。

\n\n

泛型类

\n

最常见的例子是集合。您无需创建自己的类来存储数字、字符串或自定义对象的列表,而是使用 List<T>:

\n\n
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

博客

书籍推荐