windows C#-泛型类型
泛型向 .NET 引入了类型参数的概念。 泛型支持设计类和方法,你可在在代码中使用该类或方法时,再定义一个或多个类型参数的规范。 例如,通过使用泛型类型参数 T
,可以编写其他客户端代码能够使用的单个类,而不会产生运行时转换或装箱操作的成本或风险,如下所示:
// Declare the generic class.
public class GenericList<T>
{
public void Add(T input) { }
}
class TestGenericList
{
private class ExampleClass { }
static void Main()
{
// Declare a list of type int.
GenericList<int> list1 = new GenericList<int>();
list1.Add(1);
// Declare a list of type string.
GenericList<string> list2 = new GenericList<string>();
list2.Add("");
// Declare a list of type ExampleClass.
GenericList<ExampleClass> list3 = new GenericList<ExampleClass>();
list3.Add(new ExampleClass());
}
}
泛型类和泛型方法兼具可重用性、类型安全性和效率,这是非泛型类和非泛型方法无法实现的。 在编译过程中将泛型类型参数替换为类型参数。 在前面的示例中,编译器会使用 int 替换 T。 泛型通常与集合以及作用于集合的方法一起使用。 System.Collections.Generic 命名空间包含几个基于泛型的集合类。 不建议使用非泛型集合(如 ArrayList),并且仅出于兼容性目的而维护非泛型集合。
你也可创建自定义泛型类型和泛型方法,以提供自己的通用解决方案,设计类型安全的高效模式。 以下代码示例演示了出于演示目的的简单泛型链接列表类。 (大多数情况下,应使用 .NET 提供的 List<T> 类,而不是自行创建类。)在通常使用具体类型来指示列表中所存储项的类型的情况下,可使用类型参数 T:
- 在 AddHead 方法中作为方法参数的类型;
- 在 Node 嵌套类中作为 Data 属性的返回类型;
- 在嵌套类中作为私有成员 data 的类型;
T 可用于 Node 嵌套类。 如果使用具体类型实例化 GenericList<T>(例如,作为 GenericList<int>),则出现的所有 T 都将替换为 int。
// type parameter T in angle brackets
public class GenericList<T>
{
// The nested class is also generic on T.
private class Node
{
// T used in non-generic constructor.
public Node(T t)
{
next = null;
data = t;
}
private Node? next;
public Node? Next
{
get { return next; }
set { next = value; }
}
// T as private member data type.
private T data;
// T as return type of property.
public T Data
{
get { return data; }
set { data = value; }
}
}
private Node? head;
// constructor
public GenericList()
{
head = null;
}
// T as method parameter type:
public void AddHead(T t)
{
Node n = new Node(t);
n.Next = head;
head = n;
}
public IEnumerator<T> GetEnumerator()
{
Node? current = head;
while (current != null)
{
yield return current.Data;
current = current.Next;
}
}
}
以下代码示例演示了客户端代码如何使用泛型 GenericList<T> 类来创建整数列表。 如果更改类型参数,以下代码将创建字符串列表或任何其他自定义类型:
class TestGenericList
{
static void Main()
{
// int is the type argument
GenericList<int> list = new GenericList<int>();
for (int x = 0; x < 10; x++)
{
list.AddHead(x);
}
foreach (int i in list)
{
System.Console.Write(i + " ");
}
System.Console.WriteLine("\nDone");
}
}
泛型类型不限于类。 前面的示例使用了 class 类型,但你可以定义泛型 interface 和 struct 类型,包括 record 类型。
泛型概述
- 使用泛型类型可以最大限度地重用代码、保护类型安全性以及提高性能;
- 泛型最常见的用途是创建集合类;
- .NET 类库在 System.Collections.Generic 命名空间中包含几个新的泛型集合类。 应尽可能使用泛型集合来代替某些类,如 System.Collections 命名空间中的 ArrayList;
- 可以创建自己的泛型接口、泛型类、泛型方法、泛型事件和泛型委托;
- 可以对泛型类进行约束以访问特定数据类型的方法;
- 可以使用反射在运行时获取有关泛型数据类型中使用的类型的信息;