C# 中的泛型(Generics)
在 C# 编程语言中,泛型(Generics)是一种强大的功能,它允许在定义类、接口、方法和委托时使用类型参数。泛型使代码更具通用性和重用性,并在编译时进行类型检查,从而提高了类型安全性和运行时性能。本文将详细介绍 C# 中的泛型及其各种用法。
泛型的主要特性
- 类型安全性:泛型在编译时进行类型检查,防止了类型转换错误,确保代码的安全性。
- 代码重用:泛型允许编写通用的代码,可用于处理不同的数据类型,显著提高代码的复用性。
- 性能优化:避免了装箱(boxing)和拆箱(unboxing)操作,特别是在处理值类型时,提升了性能。
- 类型参数约束:通过类型参数约束,可以限制泛型类型参数的类型,增强了灵活性和安全性。
一、泛型类
泛型类允许使用类型参数来定义类,这样同一个类可以处理不同的数据类型。
定义泛型类
public class GenericList<T>
{
private T[] items;
private int count;
public GenericList(int capacity)
{
items = new T[capacity];
count = 0;
}
public void Add(T item)
{
if (count < items.Length)
{
items[count] = item;
count++;
}
else
{
throw new InvalidOperationException("List is full.");
}
}
public T Get(int index)
{
if (index >= 0 && index < count)
{
return items[index];
}
else
{
throw new ArgumentOutOfRangeException("index");
}
}
}
使用泛型类
var intList = new GenericList<int>(5);
intList.Add(1);
intList.Add(2);
var stringList = new GenericList<string>(5);
stringList.Add("Hello");
stringList.Add("World");
二、泛型方法
泛型方法允许在方法级别使用类型参数,适用于需要处理不同类型的通用方法。
定义泛型方法
public class Utilities
{
public T GetDefaultValue<T>()
{
return default(T);
}
}
使用泛型方法
var utilities = new Utilities();
int defaultInt = utilities.GetDefaultValue<int>(); // 0
string defaultString = utilities.GetDefaultValue<string>(); // null
三、类型参数约束
类型参数约束允许对泛型类型参数施加条件,限制可用的类型,提高代码的安全性和灵活性。
常见的类型参数约束
where T : struct:T 必须是值类型。where T : class:T 必须是引用类型。where T : new():T 必须有一个无参数的构造函数。where T : BaseClass:T 必须继承自 BaseClass。where T : interfaceName:T 必须实现 interfaceName 接口。
示例
public class GenericClass<T> where T : IComparable
{
public bool IsGreater(T a, T b)
{
return a.CompareTo(b) > 0;
}
}
四、泛型接口
泛型接口允许定义具有通用类型参数的接口,适用于需要定义通用行为的场景。
定义泛型接口
public interface IRepository<T>
{
void Add(T item);
T Get(int id);
}
实现泛型接口
public class Repository<T> : IRepository<T>
{
private List<T> items = new List<T>();
public void Add(T item)
{
items.Add(item);
}
public T Get(int id)
{
return items[id];
}
}
五、泛型委托
泛型委托允许定义通用的委托类型,可以处理不同类型的参数和返回值。
定义泛型委托
public delegate T Operation<T>(T a, T b);
public class MathOperations
{
public T Add<T>(T a, T b)
{
return (dynamic)a + (dynamic)b;
}
}
使用泛型委托
Operation<int> addOperation = new MathOperations().Add;
int result = addOperation(5, 3); // 8
六、常用的泛型集合类
.NET 提供了丰富的泛型集合类,它们在实际开发中非常常用。
常用泛型集合类
List<T>:动态数组。Dictionary<TKey, TValue>:键值对集合。Queue<T>:先进先出(FIFO)集合。Stack<T>:后进先出(LIFO)集合。HashSet<T>:无序集合,保证元素唯一。
使用 List<T>
var intList = new List<int> { 1, 2, 3, 4, 5 };
intList.Add(6);
foreach (var item in intList)
{
Console.WriteLine(item);
}
总结
C# 中的泛型提供了类型安全性、代码重用和性能优化的优势。通过泛型类、泛型方法、泛型接口和泛型委托,开发者可以编写更通用、更灵活的代码。此外,类型参数约束进一步增强了泛型的实用性和安全性。在日常开发中,合理使用泛型可以显著提高代码质量和开发效率。无论是处理集合数据还是定义通用算法,泛型都是一种强大的工具。