泛型是「型別參數化」技術,允許在定義類別、方法、介面、委派時以型別參數(如 T)佔位,實際使用時再指定具體型別。核心價值在於型別安全與效能(避免裝箱/拆箱)。
public class PersonCollection : IList
{
private ArrayList _list = new();
public Person this[int i] => (Person)_list[i]; // 需轉型,執行期才知對錯
public int Add(Person p) => _list.Add(p);
// 實作 IList 成員需大量轉型程式碼
}
每新增一種型別(如 Dog)就得複製一份集合類別 → 程式碼重複、維護困難。
var persons = new List();
persons.Add(new Person());
Person p = persons[0]; // 編譯期保證型別正確,無轉型
var dogs = new List();
dogs.Add(new Dog());
Dog d = dogs[0];
單一 List 服務所有型別,編譯器自動生成型別安全的程式碼。
// 非泛型:值類型進 ArrayList 必須裝箱
var ints = new IntCollection(); // 內部用 ArrayList
ints.Add(5); // 裝箱
int i = ints[0]; // 拆箱
// 泛型:零裝箱/拆箱
var ints = new List();
ints.Add(5); // 直接儲存 int
int i = ints[0]; // 直接讀取 int
大量值類型集合操作時,效能差異顯著。
static void Swap(ref T a, ref T b)
{
T temp = a; a = b; b = temp;
}
Swap(ref x, ref y); // 型別推論
public class Point
{
public T X { get; set; }
public T Y { get; set; }
public override string ToString() => $"[{X}, {Y}]";
}
| 約束 | 語法 | 說明 |
|---|---|---|
| 實質型別 | where T : struct | 不可為 nullable |
| 參考型別 | where T : class | 類別、介面、委派、陣列 |
| 預設建構函式 | where T : new() | public 無參數建構函式 |
| 基類/介面 | where T : Base | 繼承或實作 |
可組合:where T : class, IComparable, new()。
List),以實際型別取代佔位符產生機器碼。泛型實現程式碼的橫向復用(相同邏輯套用不同型別),補足繼承的縱向復用。類似 AOP 思想,將「型別」作為參數傳遞,讓編譯器在型別層面驗證邏輯一致性。
泛型是 .NET 類型系統的基石,掌握型別參數化、約束、JIT 實例化與程式碼共享機制,能設計出高效能、強型別、可維護的元件庫。現代 C# 進一步引入泛型數學介面、預設介面方法,持續擴展泛型表達力。