泛型型別和方法

泛型會將類型參數的概念引入 .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());
    }
}

泛型類別和方法會以非泛型對應項目無法的方式結合可重複使用性、型別安全性和效率。 泛型型別參數會在編譯期間取代為類型自變數。 在上述範例中,編譯程式會將 T 取代為 int。 泛型最常搭配在其上操作的集合和方法使用。 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 類型,包括 record 類型。

泛型概觀

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

C# 語言規格

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

另請參閱