首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 泛型深度解析:型別安全、效能提升與執行機制

     編輯:關於C#

什麼是泛型

泛型 是「型別參數化」:在定義類別、方法、介面、委派時,將具體型別延遲到使用時才指定。如 List<T> 中的 T 為型別參數,實例化時決定為 int、string 或自訂類別。

兩大核心優勢

  1. 型別安全:編譯期檢查,避免執行期 InvalidCastException。
  2. 消除裝箱/拆箱:實值型別直接儲存於泛型集合內部陣列,不轉為 object,大幅提升效能與減少 GC 壓力。

對比:非泛型 vs 泛型集合

非泛型實作型別安全(繁瑣)


public class PersonCollection : IList
{
    private ArrayList _list = new ArrayList();
    public Person this[int i] { get { return (Person)_list[i]; } }
    public int Add(Person p) { _list.Add(p); return _list.Count - 1; }
    // 必須顯式實作 IList 介面,大量轉型程式碼...
    object IList.this[int i] { get { return _list[i]; } set { _list[i] = (Person)value; } }
    int IList.Add(object o) { return Add((Person)o); }
    // 若要支援 Dog、Order 等類別,必須複製修改類別名稱...
}

泛型一行解決


List persons = new List();
persons.Add(new Person());
Person p = persons[0]; // 無轉型、型別安全

List dogs = new List();
dogs.Add(new Dog());
Dog d = dogs[0];

實值型別裝箱/拆箱對比


// 非泛型 ArrayList
ArrayList list = new ArrayList();
list.Add(5);      // 裝箱:int → object
int i = (int)list[0]; // 拆箱:object → int

// 泛型 List
List list2 = new List();
list2.Add(5);     // 無裝箱
int j = list2[0]; // 無拆箱

大量資料時,裝箱/拆箱產生大量暫存物件,觸發 Gen 0 GC,影響效能。泛型避免此問題。

泛型語法全景

泛型方法


static void Swap(ref T a, ref T b)
{
    Console.WriteLine("Type: {0}", typeof(T));
    T temp = a; a = b; b = temp;
}

泛型類別/結構


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 : BaseClass / where T : IInterface限定繼承鏈
組合約束where T : class, IComparable, new()多重條件

執行階段機制

  1. 編譯階段:C# 編譯器產生含型別參數佔位符的 IL 與中繼資料,不具現化。
  2. JIT 編譯階段:首次遇到 List<int> 等封閉構造型別,CLR 以實際型別替換佔位符產生機器碼。
    • 所有 參考型別 共用同一份機器碼(如 List<string>、List<object>)。
    • 每個 實值型別 產生獨立機器碼(List<int>、List<double> 各一份),確保正確的記憶體配置與指令。

已知限制

  • 不支援運算子多載(無法在泛型方法中直接使用 +、- 等運算子,需透過介面或 dynamic)。
  • 靜態成員每個封閉構造型別各自一份(MyClass<int>.StaticField 與 MyClass<string>.StaticField 獨立)。
  • 無法對型別參數使用 typeof(T) 取得泛型定義(需 typeof(MyClass<>))。

泛型的設計意義

泛型不只是型別安全與效能工具,更實現了「橫向抽象」:將演算法與資料結構從具體型別解耦,類似 AOP 的關注點分離。繼承提供「縱向」關係(is-a),泛型提供「橫向」關係(演算法套用於任意型別)。這種抽象能力是現代靜態型別語言表達力的關鍵。

結語

精通泛型約束、共變/反變、執行機制,能設計出高效能、高重用的程式庫。日常開發請優先使用 List<T>、Dictionary<TKey,TValue> 等內建泛型集合,避免 ArrayList、Hashtable 等非泛型類別。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved