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

泛型引進 .NET Framework 的型別參數概念,讓您可以設計類別和方法,以延遲一或多個類型的規格,直到用戶端程式代碼宣告並具現化類別或方法為止。Generics introduce the concept of type parameters to the .NET Framework, 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. System.Collections.Generic 命名空間包含數個以泛型為基礎的集合類別。The System.Collections.Generic namespace contains several generic-based collection classes. 不建議使用非泛型集合(例如 ArrayList),而是為了相容性而保留。The non-generic collections, such as ArrayList are not recommended and are maintained for compatibility purposes. 如需詳細資訊,請參閱 .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 Class Library 所提供的 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 可供 nested 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.

C# 語言規格C# language specification

如需詳細資訊,請參閱<C# 語言規格>。For more information, see the C# Language Specification.

請參閱See also