泛型是 C# 2.0 引入的核心特性,提供型別安全、效能提升(避免裝箱/拆箱)、程式碼重用三大優勢。本文系統梳理泛型類別、介面、委派、方法、約束、繼承與協變/逆變。
[Serializable]
public class List<T> : IList<T>, ICollection<T>, IEnumerable<T> {
public T this[int index] { get; set; }
public void Add(T item);
public bool Contains(T item);
public T[] ToArray();
// ...
}
<T> 為型別參數,命名慣例以 T 開頭(TKey, TValue)。使用時指定實際型別:
var list = new List<int>();
list.Add(1); // 型別安全:編譯期阻擋 list.Add("str")
int val = list[0]; // 無裝箱/拆箱,直接存取
int、double、string 等任何實作 IComparable<T> 的型別。object 造成裝箱效能損耗,且編譯期攔截型別不匹配錯誤。ObservableCollection<T>:集合變更觸發 CollectionChanged 事件,WPF/MVVM 資料綁定必備。BlockingCollection<T>:執行緒安全、支援生產者/消費者模式、可設定容量上限與 CompleteAdding。class MyOther<T> : MyBaseclass MyDerived : MyOther<int>(不可寫 MyOther<T>)class MyDerived<T> : MyOther<T>介面泛型化避免裝箱:IComparable<T>.CompareTo(T other) vs IComparable.CompareTo(object obj)。
委派泛型化:Action<T>(無回傳)、Func<T, TResult>(有回傳)、Predicate<T>(回傳 bool),框架內建支援至 16 參數。
型別參數宣告於方法層級:
public TParam CompareTo<TParam>(TParam other) { ... }
呼叫時編譯器自動推斷型別:obj.CompareTo(4) → TParam = int。若多個參數同為 T,推斷要求實參型別一致。
class MyClass<T> where T : IComparable<T>, new(), class { ... }
| 約束 | 含義 |
|---|---|
where T : class | T 必為參考型別 |
where T : struct | T 必為實值型別 |
where T : new() | T 必有公用無參建構子 |
where T : BaseClass | T 必繼承自 BaseClass |
where T : IInterface | T 必實作介面 |
無約束時,使用 default(T) 取得型別預設值(參考型別 null、實值型別 0)。
預設泛型為不變性:List<string> 不能指派給 List<object>。
協變:out T 僅作輸出(回傳值),允許 IEnumerable<string> → IEnumerable<object>。
逆變:in T 僅作輸入(參數),允許 Action<object> → Action<string>。
委派範例:delegate TResult Func<in T, out TResult>(T arg);