泛型 (C# 程式設計手冊)Generics (C# Programming Guide)

泛型是在 C# 語言和 Common Language Runtime (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,撰寫一個類別供其他用戶端程式碼使用,而不會在執行階段產生轉換或 boxing 作業的成本或風險,如下所示: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 和更新版本為目標的所有應用程式都使用新的泛型集合類別,而不是舊版的非泛型集合類別,例如 ArrayListIt 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 都會以 int 取代。When 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 命名空間中的 ArrayList 類別。These 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