泛型(C# 编程指南)Generics (C# Programming Guide)

C# 语言和公共语言运行时 (CLR) 的 2.0 版本中添加了泛型。Generics were added to version 2.0 of the C# language and the common language runtime (CLR). 泛型将类型参数的概念引入 .NET Framework,这样就可以设计具有以下特征的类和方法:在客户端代码声明并初始化这些类和方法之前,这些类和方法会延迟指定一个或多个类型。Generics introduce to the .NET Framework the concept of type parameters, which make it possible to design classes and methods that defer the specification of one or more types until the class or method is declared and instantiated by client code. 例如,通过使用泛型类型参数 T,可以编写其他客户端代码能够使用的单个类,而不会产生运行时转换或装箱操作的成本或风险,如下所示:For example, by using a generic type parameter T you can write a single class that other client code can use without incurring the cost or risk of runtime casts or boxing operations, as shown here:

// 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());
    }
}

泛型类和泛型方法兼具可重用性、类型安全性和效率,这是非泛型类和非泛型方法无法实现的。Generic classes and methods combine reusability, type safety and efficiency in a way that their non-generic counterparts cannot. 泛型通常与集合以及作用于集合的方法一起使用。Generics are most frequently used with collections and the methods that operate on them. .NET Framework 2.0 版类库提供新的命名空间 System.Collections.Generic,其中包含几个新的基于泛型的集合类。Version 2.0 of the .NET Framework class library provides a new namespace, System.Collections.Generic, which contains several new generic-based collection classes. 建议所有定目标到 .NET Framework 2.0 及更高版本的应用程序都使用新增的泛型集合类,而不是旧的非泛型集合类(如 ArrayList)。It is recommended that all applications that target the .NET Framework 2.0 and later use the new generic collection classes instead of the older non-generic counterparts such as ArrayList. 有关详细信息,请参阅 .NET 中的泛型For more information, see Generics in .NET.

当然,也可以创建自定义泛型类型和泛型方法,以提供自己的通用解决方案,设计类型安全的高效模式。Of course, you can also create custom generic types and methods to provide your own generalized solutions and design patterns that are type-safe and efficient. 以下代码示例演示了出于演示目的的简单泛型链接列表类。The following code example shows a simple generic linked-list class for demonstration purposes. (大多数情况下,应使用 .NET Framework 类库提供的 List<T> 类,而不是自行创建类。)在通常使用具体类型来指示列表中所存储项的类型的情况下,可使用类型参数 T(In most cases, you should use the List<T> class provided by the .NET Framework class library instead of creating your own.) The type parameter T is used in several locations where a concrete type would ordinarily be used to indicate the type of the item stored in the list. 其使用方法如下:It is used in the following ways:

  • AddHead 方法中作为方法参数的类型。As the type of a method parameter in the AddHead method.

  • Node 嵌套类中作为 Data 属性的返回类型。As the return type of the Data property in the nested Node class.

  • 在嵌套类中作为私有成员 data 的类型。As the type of the private member data in the nested class.

请注意,T 可用于 Node 嵌套类。Note that T is available to the nested Node class. 如果使用具体类型实例化 GenericList<T>(例如,作为 GenericList<int>),则出现的所有 T 都将替换为 intWhen GenericList<T> is instantiated with a concrete type, for example as a GenericList<int>, each occurrence of T will be replaced with 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> 类来创建整数列表。The following code example shows how client code uses the generic GenericList<T> class to create a list of integers. 只需更改类型参数,即可轻松修改以下代码,创建字符串或任何其他自定义类型的列表:Simply by changing the type argument, the following code could easily be modified to create lists of strings or any other custom type:

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");
    }
}

泛型概述Generics Overview

  • 使用泛型类型可以最大限度地重用代码、保护类型安全性以及提高性能。Use generic types to maximize code reuse, type safety, and performance.

  • 泛型最常见的用途是创建集合类。The most common use of generics is to create collection classes.

  • .NET Framework 类库在 System.Collections.Generic 命名空间中包含几个新的泛型集合类。The .NET Framework class library contains several new generic collection classes in the System.Collections.Generic namespace. 应尽可能使用这些类来代替某些类,如 System.Collections 命名空间中的 ArrayListThese should be used whenever possible instead of classes such as ArrayList in the System.Collections namespace.

  • 可以创建自己的泛型接口、泛型类、泛型方法、泛型事件和泛型委托。You can create your own generic interfaces, classes, methods, events and delegates.

  • 可以对泛型类进行约束以访问特定数据类型的方法。Generic classes may be constrained to enable access to methods on particular data types.

  • 在泛型数据类型中所用类型的信息可在运行时通过使用反射来获取。Information on the types that are used in a generic data type may be obtained at run-time by using reflection.

更多相关信息:For more information:

C# 语言规范C# Language Specification

有关详细信息,请参阅 C# 语言规范For more information, see the C# Language Specification.

请参阅See also