泛型是 C# 2.0 引入的里程碑功能,但並非所有場合都適合使用。本文提供決策框架,幫助開發者判斷何時應採用泛型、何時該保持非泛型設計,並說明泛型帶來的四大核心效益。
適用場景:集合類別、容器、工具類(如 List<T>、Dictionary<TKey, TValue>、Repository<T>)
判斷邏輯:若類別設計初衷是「容納各種型別」,泛型能提供型別參數化優勢。若類別只操作單一固定型別(如 CustomerRepository 只處理 Customer),則無需泛型。
關鍵指標:頻繁存取 int、double、struct 等值型別
效益:泛型消除裝箱/拆箱,避免記憶體分配與 GC 壓力。效能敏感路徑(高頻呼叫、大量資料)尤為關鍵。
痛點:非泛型集合的型別錯誤只在執行期暴露(InvalidCastException)
泛型優勢:型別不匹配在編譯期即報錯(CS1503、CS0029),大幅縮短 Bug 修復週期,「越早發現錯誤,修復成本越低」。
典型症狀:為支援不同型別,複製貼上近似類別(StreamReaderList、StreamWriterList、CustomerList...)
泛型解法:撰寫單一 GenericList<T>,型別參數化替代程式碼複製。維護單一原始碼,減少錯誤傳播風險。
對比:
// 非泛型:意圖不明,充滿轉型
var list = new ArrayList();
list.Add(customer);
var c = (Customer)list[0];
// 泛型:意圖明確,自我文件化
var list = new List<Customer>();
list.Add(customer);
var c = list[0]; // 型別資訊一目瞭然
| 效益 | 說明 | 影響層面 |
|---|---|---|
| 程式碼重用 | 單一泛型定義服務無限型別 | 開發效率、維護成本 |
| 執行效能 | 值型別零裝箱、JIT 專屬最佳化 | CPU、記憶體、GC |
| 型別安全 | 編譯期強型別檢查 | 可靠度、除錯效率 |
| 程式碼清晰 | 消除轉型、意圖顯性化 | 可讀性、團隊協作 |
ArrayList → List<T>)ArrayList 實作 ICloneable,List<T> 未實作,需用 GetRange 替代泛型非萬靈丹,但對於「操作未知型別」、「處理值型別」、「追求型別安全」的場景,它是現代 C# 開發的標準解法。掌握決策標準,避免過度設計(如單一固定型別業務類別強行泛型化),才能發揮泛型最大價值。