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

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

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

开始课程

C# 中泛型(Generics)简介



泛型(Generics)是 C# 语言中最强大的功能之一,自 .NET Framework 2.0 引入。它们允许创建能够处理任何数据类型、同时保持严格类型检查的类、方法和接口。在本文中,我们将探讨C# 中为什么需要泛型,如何使用它们以及它们为开发者带来的优势。



假设您需要编写一个交换两个变量值的方法。没有泛型时,您必须为每种类型创建单独的方法:SwapInt、SwapString、SwapDouble 等等。而使用泛型,这个任务可以通过一个通用函数解决。



泛型的主要优势



1. 编译时类型安全



泛型在编译时而非运行时提供类型检查。这意味着与类型不匹配相关的错误将在开发早期被发现。



// 没有泛型 - 运行时可能出错ArrayList list = new ArrayList();list.Add(123);list.Add("строка");int number = (int)list[1]; // InvalidCastException!

// 使用泛型 - 编译时出错List<int> numbers = new List<int>();numbers.Add(123);numbers.Add("строка"); // 编译错误!


2. 性能



使用泛型可以避免值类型的装箱(boxing)和拆箱(unboxing)操作。这显著提高了处理集合时的性能。



// 装箱/拆箱 - 速度慢ArrayList list = new ArrayList();list.Add(42); // boxingint value = (int)list[0]; // unboxing

// 泛型 - 速度快,无需 boxingList<int> list = new List<int>();list.Add(42); // 无需 boxingint value = list[0]; // 无需 unboxing


3. 代码重用



一个泛型类或方法可以处理任何数据类型,从而避免了代码重复。



创建和使用泛型



泛型类



让我们看一个创建用于存储键值对的泛型类的示例:



public class Pair<TFirst, TSecond>{    public TFirst First { get; set; }    public TSecond Second { get; set; }        public Pair(TFirst first, TSecond second)    {        First = first;        Second = second;    }        public void Display()    {        Console.WriteLine($"First: {First}, Second: {Second}");    }}

// 使用var pair1 = new Pair<int, string>(1, "один");var pair2 = new Pair<string, double>("PI", 3.14159);

pair1.Display(); // First: 1, Second: одинpair2.Display(); // First: PI, Second: 3.14159


泛型方法



方法也可以是泛型的。这是一个经典示例——值交换方法:



public static void Swap<T>(ref T a, ref T b){    T temp = a;    a = b;    b = temp;}

// 使用int x = 5, y = 10;Swap<int>(ref x, ref y);Console.WriteLine($"x = {x}, y = {y}"); // x = 10, y = 5

string s1 = "Hello", s2 = "World";Swap(ref s1, ref s2); // 类型可以省略Console.WriteLine($"s1 = {s1}, s2 = {s2}"); // s1 = World, s2 = Hello


泛型接口



带有泛型的接口允许创建灵活的契约:



public interface IRepository<T>{    T GetById(int id);    void Add(T entity);    void Update(T entity);    void Delete(int id);}

public class UserRepository : IRepository<User>{ public User GetById(int id) { // 获取用户的实现 return new User(); } public void Add(User user) { // 添加的实现 } public void Update(User user) { // 更新的实现 }

博客

书籍推荐