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
),以提高代码的类型安全性和性能。
附加资源
练习
- 创建一个泛型类
Stack<T>
,实现基本的栈操作(Push、Pop、Peek)。 - 编写一个泛型方法
Swap<T>
,用于交换两个变量的值。 - 创建一个泛型接口
ISorter<T>
,并实现一个类BubbleSorter<T>
,用于对数组进行冒泡排序。
通过完成这些练习,你将更好地理解泛型的概念和应用。