泛型型別和方法
泛型會將類型參數的概念引入 .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
類型,但您可以定義泛型 interface
和 struct
類型,包括 record
類型。
泛型概觀
- 使用泛型型別以最佳化程式碼重複使用、型別安全和效能。
- 泛型的最常見用法是建立集合類別。
- .NET 類別庫包含 System.Collections.Generic 命名空間中的一些新泛型集合類別。 您應該盡可能使用泛型集合,而不是使用類似在 System.Collections 命名空間中的 ArrayList 類別。
- 您可以建立自己的泛型介面、類別、方法、事件和委派。
- 泛型類別可以限制為在特定數據類型上啟用方法的存取。
- 您可以在運行時間取得泛型數據類型中所使用的類型資訊,方法是使用反映。
C# 語言規格
如需詳細資訊,請參閱<C# 語言規格>。