C# 泛型(Generic)
泛型是一种强类型的编程机制,它允许在编译时指定类型参数,从而可以在不同的数据类型上重用代码。C# 泛型使得开发人员可以创建具有通用性的方法、类和数据结构,提高了代码的可读性、可维护性和可扩展性。
# 泛型的优势
- 提高代码的复用性
- 编译时类型检查,避免运行时类型转换错误
- 提高代码的可读性和可维护性
# 泛型的语法
在C#中,使用尖括号来声明泛型类型参数。语法如下:
class ClassName<T>
{
//泛型类成员声明
}
interface InterfaceName<T>
{
//泛型接口成员声明
}
delegate T MyDelegate<T>(T t);
void GenericMethod<T>(T t)
{
//泛型方法体
}
在上面的语法中,T是类型参数,可以在类、接口、方法和委托中使用。
# 泛型类
泛型类是一种具有通用性的类,它可以在编译时指定类型参数。例如,下面是一个泛型栈类的实现:
public class Stack<T>
{
private T[] elements;
private int top;
public Stack(int capacity)
{
elements = new T[capacity];
top = -1;
}
public void Push(T item)
{
if (top == elements.Length - 1)
{
throw new StackOverflowException();
}
elements[++top] = item;
}
public T Pop()
{
if (top == -1)
{
throw new InvalidOperationException();
}
return elements[top--];
}
}
在上面的代码中,我们声明了一个泛型类Stack<T>
,它包含了一个数组和两个方法Push()
和Pop()
。在构造函数中,我们创建了一个指定容量的数组,并将top初始化为-1。在Push()方法中,我们向数组中添加元素,并将top加1。在Pop()方法中,我们从数组中取出一个元素,并将top减1。
# 泛型方法
泛型方法是一种具有通用性的方法,它可以在编译时指定类型参数。例如,下面是一个泛型方法的实现:
public static T Max<T>(T first, T second) where T : IComparable<T>
{
if (first.CompareTo(second) > 0)
{
return first;
}
return second;
}
在上面的代码中,我们声明了一个泛型方法Max<T>()
,它接受两个参数,并返回一个类型为T的值。在方法体中,我们使用IComparable<T>
接口的CompareTo()
方法来比较两个参数的大小,并返回较大的值。
# 泛型接口
泛型接口是一种具有通用性的接口,它可以在编译时指定类型参数。例如,下面是一个泛型接口的实现:
public interface IMyInterface<T>
{
T GetResult();
}
public class MyClass : IMyInterface<int>
{
public int GetResult()
{
return 42;
}
}
在上面的代码中,我们声明了一个泛型接口IMyInterface<T>
,它包含一个GetResult()
方法。在实现类MyClass
中,我们指定类型参数为int
,并实现了GetResult()
方法。
# 泛型约束
泛型约束可以限制泛型类型参数的类型,从而提高代码的安全性和可读性。例如,我们可以使用where关键字来指定泛型类型参数必须实现指定的接口或派生自指定的类。例如:
public static void Print<T>(T value) where T : IComparable<T>
{
Console.WriteLine(value.CompareTo(default(T)) > 0 ? value.ToString() : "default");
}
在上面的代码中,我们使用泛型约束来限制类型参数T必须实现IComparable<T>
接口。在方法体中,我们使用CompareTo()
方法比较value和默认值的大小,并输出相应的结果。
# 总结
C#泛型为开发人员提供了一种通用性的编程机制,可以提高代码的可读性、可维护性和可扩展性。泛型类、泛型方法和泛型接口等都是基于泛型的核心概念实现的。通过使用泛型约束,我们可以限制泛型类型参数的类型,从而提高代码的安全性和可读性。