泛型介绍(C# 编程指南)Introduction to Generics (C# Programming Guide)

泛型类和泛型方法兼具可重用性、类型安全性和效率,这是非泛型类和非泛型方法无法实现的。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");
    }
}

请参阅See also