跳到主要内容

C# 泛型

介绍

在 C# 中,泛型(Generics)是一种强大的特性,它允许你编写可以与多种数据类型一起工作的类、方法和接口,而无需为每种数据类型编写重复的代码。泛型的主要目的是提高代码的可重用性和类型安全性。

通过泛型,你可以创建通用的类或方法,这些类或方法可以处理任何类型的数据,同时避免装箱和拆箱操作,从而提高性能。

泛型的基本概念

泛型类

泛型类是一个可以处理任何数据类型的类。你可以通过在类定义中使用类型参数来实现这一点。例如:

csharp
public class Box<T>
{
public T Content { get; set; }

public Box(T content)
{
Content = content;
}
}

在这个例子中,Box<T> 是一个泛型类,T 是类型参数。你可以使用这个类来存储任何类型的数据:

csharp
Box<int> intBox = new Box<int>(123);
Box<string> stringBox = new Box<string>("Hello, Generics!");

泛型方法

泛型方法允许你在方法中使用类型参数。例如:

csharp
public void Print<T>(T value)
{
Console.WriteLine(value);
}

你可以调用这个方法来打印任何类型的值:

csharp
Print(42); // 输出: 42
Print("Hello"); // 输出: Hello

泛型约束

有时你可能希望限制泛型类型参数的类型。你可以使用泛型约束来实现这一点。例如,你可以指定类型参数必须实现某个接口或继承自某个类:

csharp
public class Box<T> where T : IComparable
{
public T Content { get; set; }

public Box(T content)
{
Content = content;
}
}

在这个例子中,T 必须实现 IComparable 接口。

实际应用场景

集合类

C# 中的集合类(如 List<T>Dictionary<TKey, TValue>)是泛型的典型应用。它们允许你创建类型安全的集合,而不需要为每种数据类型编写单独的集合类。

csharp
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
List<string> names = new List<string> { "Alice", "Bob", "Charlie" };

泛型接口

泛型接口允许你定义可以处理多种数据类型的接口。例如:

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

你可以为不同的实体类型实现这个接口:

csharp
public class ProductRepository : IRepository<Product>
{
public void Add(Product product)
{
// 添加产品的逻辑
}

public Product GetById(int id)
{
// 根据ID获取产品的逻辑
return new Product();
}
}

总结

泛型是 C# 中一个非常强大的特性,它可以帮助你编写更加灵活、可重用和类型安全的代码。通过泛型,你可以避免重复代码,并提高应用程序的性能。

提示

在实际开发中,尽量使用泛型来替代非泛型集合类(如 ArrayList),以提高代码的类型安全性和性能。

附加资源

练习

  1. 创建一个泛型类 Stack<T>,实现基本的栈操作(Push、Pop、Peek)。
  2. 编写一个泛型方法 Swap<T>,用于交换两个变量的值。
  3. 创建一个泛型接口 ISorter<T>,并实现一个类 BubbleSorter<T>,用于对数组进行冒泡排序。

通过完成这些练习,你将更好地理解泛型的概念和应用。