泛型型別和方法

泛型會介紹 .NET 的類型參數概念,這可讓您設計類別和方法,以延遲一或多個類型的規格,直到用戶端程式代碼宣告和具現化類別或方法為止。 例如,您可以使用泛型型別參數 T,撰寫一個類別供其他用戶端程式碼使用,而不會在執行階段產生轉換或 boxing 作業的成本或風險,如下所示:

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

泛型型別和方法將再使用性、型別安全和效率三者結合在一起,發揮了非泛型型別和方法所無法提供的功能。 泛型最常搭配在其上操作的集合和方法使用。 System.Collections.Generic 命名空間包含數個泛型集合類別。 不建議使用非泛型集合,例如 ArrayList,非泛型集合會為了相容性而維護。 如需詳細資訊,請參閱 .NET 的泛型

您也可以建立自訂的泛型型別和方法,自行處理泛型化的問題,並設計型別安全且有效率的模式。 下列程式碼範例顯示一個簡單的泛型連結清單類別,以供示範之用 (在大部分情況下,您應該使用 List<T> .NET 提供的 類別,而不是建立您自己的。) 類型參數 T 用於數個位置,其中一般會使用具象類型來指出儲存在清單中的專案類型。 這個參數可以用於下列方面:

  • 作為 AddHead 方法中的方法參數類型。
  • 作為巢狀 Node 類別中 Data 屬性的傳回型別。
  • 作為巢狀類別中私用成員 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 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> 類別建立整數清單。 您只要變更型別引數,就能輕鬆修改下列的程式碼來建立字串清單或任何其他自訂類型的清單:

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

注意

下列範例不僅 class 適用于類型,也適用于 interfacestruct 類型

泛型概觀

  • 使用泛型型別以最佳化程式碼重複使用、型別安全和效能。
  • 泛型的最常見用法是建立集合類別。
  • .NET 類別庫包含命名空間中的 System.Collections.Generic 數個泛型集合類別。 您應該盡可能使用泛型集合,而不是使用類似在 System.Collections 命名空間中的 ArrayList 類別。
  • 您可以建立自己的泛型介面、類別、方法、事件和委派。
  • 泛型類別可限制為允許存取特定資料類型上的方法。
  • 泛型資料類型中所使用的類型相關資訊,可在執行階段透過反映取得。

C# 語言規格

如需詳細資訊,請參閱<C# 語言規格>。

另請參閱