一次編寫,多型別複用。避免 object 裝箱/拆箱與型別轉換,編譯期保證型別安全,JIT 為每個封閉型別產生專屬機器碼。
using System.Collections.Generic;
List customers = new List();
customers.Add(new Customer("Motown-Jobs"));
customers.Add(new Customer("Fatman's"));
foreach (Customer c in customers)
Console.WriteLine(c.CustomerName); // 強型別,無轉換
public class CustomerList : CollectionBase
{
public Customer this[int i] { get => (Customer)List[i]; set => List[i] = value; }
public int Add(Customer c) => List.Add(c);
}
Tpublic class GenericList : CollectionBase
{
public T this[int i] { get => (T)List[i]; set => List[i] = value; }
public int Add(T item) => List.Add(item);
}
// T 必須實作 IDisposable 且有公用無參建構子
public class DisposableList : CollectionBase
where T : class, IDisposable, new()
{
public T this[int i] { get => (T)List[i]; set => List[i] = value; }
public int Add(T item) => List.Add(item);
public void DisposeAll()
{
foreach (T item in List) item.Dispose();
}
}
| 約束 | 語法 | 說明 |
|---|---|---|
| 參考型別 | where T : class | 類別、介面、委派、陣列 |
| 實值型別 | where T : struct | 除 Nullable<T> 外的結構 |
| 無參建構子 | where T : new() | 需 public 無參建構子 |
| 基類 | where T : BaseClass | 繼承指定基類 |
| 介面 | where T : IInterface | 實作指定介面(可多個) |
| 非受控型別 | where T : unmanaged | C# 7.3+,無參考欄位的結構 |
| 預設建構子 | where T : notnull | C# 8.0+,不可為 null 的型別 |
靜態欄位/建構子以封閉型別為單位獨立:
public class Counter { public static int Count; static Counter() => Count = 0; }
Counter.Count++; // 1
Counter.Count++; // 2
Counter.Count++; // 1 (獨立)
public static void Swap(ref T a, ref T b) { T t = a; a = b; b = t; }
public void PushRange(Stack stack, params T[] items)
=> Array.ForEach(items, stack.Push);
泛型是 C# 型別系統的基石,掌握「定義型別參數、替換具體型別、加入約束」三步驟,即可建立高效、型別安全、可複用的元件。