泛型类和方法

泛型向 .NET 引入了类型参数的概念。 泛型使得可以设计类和方法,将一个或多个类型参数的定义推迟到在代码中使用该类或方法时。 例如,通过使用泛型类型参数 T,可以编写一个供其他客户端代码使用的单个类,从而避免了运行时强制转换或装箱操作的成本或风险,如下所示:

// Declare the generic class.
public class GenericList<T>
{
    public void Add(T item) { }
}

public class ExampleClass { }

class TestGenericList
{
    static void Main()
    {
        // Create a list of type int.
        GenericList<int> list1 = new();
        list1.Add(1);

        // Create a list of type string.
        GenericList<string> list2 = new();
        list2.Add("");

        // Create a list of type ExampleClass.
        GenericList<ExampleClass> list3 = new();
        list3.Add(new ExampleClass());
    }
}

泛型类和方法在可重用性、类型安全性和效率方面具有非泛型类和方法无法达到的优势。 泛型类型参数在编译过程中替换为类型参数。 在前面的示例中,编译器将 T 替换为 int。 泛型最常用于集合及操作这些集合的方法。 命名空间 System.Collections.Generic 包含多个基于泛型的集合类。 不推荐使用非泛型集合,例如 ArrayList ,这些集合仅用于兼容性目的。 有关详细信息,请参阅 .NET中的 泛型。

还可以创建自定义泛型类型和方法,以提供自己的通用解决方案和设计模式,这些模式是类型安全且高效的。 下面的代码示例演示了一个简单的泛型链接列表类,用于演示目的。 (在大多数情况下,应使用 List<T> .NET 提供的类,而不是创建自己的类。类型参数 T 用于多个位置,其中具体类型通常用于指示列表中存储的项的类型:

  • AddHead 方法中作为方法参数的类型。
  • Data 嵌套类中作为 Node 属性的返回类型。
  • 在嵌套类中作为私有成员 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, and
    // holds a data item of type T.
    private class Node(T t)
    {
        // T as property type.
        public T Data { get; set; } = t;

        public Node? Next { get; set; }
    }

    // First item in the linked list
    private Node? head;

    // T as parameter type.
    public void AddHead(T t)
    {
        Node n = new(t);
        n.Next = head;
        head = n;
    }

    // T in method return type.
    public IEnumerator<T> GetEnumerator()
    {
        Node? current = head;

        while (current is not null)
        {
            yield return current.Data;
            current = current.Next;
        }
    }
}

下面的代码示例演示客户端代码如何使用泛型 GenericList<T> 类创建整数列表。 如果更改类型参数,以下代码将创建字符串列表或任何其他自定义类型:

// A generic list of int.
GenericList<int> list = new();

// Add ten int values.
for (int x = 0; x < 10; x++)
{
    list.AddHead(x);
}

// Write them to the console.
foreach (int i in list)
{
    Console.WriteLine(i);
}

Console.WriteLine("Done");

注释

泛型类型不限于类。 前面的示例使用 class 类型,但可以定义泛型 interfacestruct 类型,包括 record 类型。

泛型概述

  • 使用泛型类型最大限度地提高代码重用、类型安全性和性能。
  • 泛型的最常见用途是创建集合类。
  • .NET 类库包含命名空间中的 System.Collections.Generic 多个泛型集合类。 应尽可能使用泛型集合,而不是命名空间 ArrayList 中的 System.Collections 类。
  • 可以创建自己的泛型接口、类、方法、事件和委托。
  • 可以限制泛型类,以启用对特定数据类型的方法的访问。
  • 可以使用反射在运行时获取有关泛型数据类型中使用的类型的信息。

C# 语言规范

有关详细信息,请参阅 C# 语言规范

另请参阅