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

C# 泛型核心知識深度解析:從 IL 視角看類型安全、效能與靜態成員行為

     編輯:關於.NET

泛型是 C# 2.0 引入的核心特性,透過型別參數化實現程式碼重用與類型安全。本文從 IL 層面剖析泛型相較 ArrayList 的優勢,並深入探討泛型靜態成員的封閉型別隔離行為。

直觀比較:ArrayList vs List<int>

// ArrayList:裝箱、型別不安全、需轉型
var list1 = new ArrayList();
list1.Add(1);           // 裝箱
list1.Add("a");         // 任意型別
int i = (int)list1[0] + 1; // 拆箱 + 強制轉型,運行期可能拋 InvalidCastException

// List<int>:無裝箱、型別安全、無轉型
var list2 = new List<int>();
list2.Add(1);           // 正常
// list2.Add("a");      // 編譯錯誤
int j = list2[0] + 1;   // 直接取值運算

三大核心優勢

  1. 類型安全:編譯期強制檢查,List<int> 僅接受 int
  2. 值型別無裝箱/拆箱:直接在堆疊操作,效能顯著提升
  3. 免強制轉型:值型別與參考型別均適用,代碼更乾淨

IL 代碼證據

// ArrayList.Add(1) - 裝箱指令
IL_0009: box [mscorlib]System.Int32
IL_000e: callvirt ... ArrayList::Add(object)

// List<int>.Add(1) - 無 box 指令
IL_0037: callvirt ... List`1<int32>::Add(!0)

// ArrayList 讀取 - 拆箱
IL_0022: callvirt ... ArrayList::get_Item(int32)  // 回傳 object
IL_0027: unbox.any [mscorlib]System.Int32         // 拆箱

// List<int> 讀取 - 直接回傳 int32
IL_003f: callvirt ... List`1<int32>::get_Item(int32)  // 回傳 !0 (int32)
IL_0044: ldc.i4.1

結構函式差異:

// ArrayList
IL_0001: newobj ... ArrayList::.ctor()

// List<int> - 具體化型別參數
IL_002f: newobj ... List`1<int32>::.ctor()

泛型實例化機制

  1. 編譯期:產生 IL,T 為佔位符
  2. 執行期 (JIT):依實際型別參數 (如 int) 產生機器碼,T 被實際型別取代
  3. 每個封閉構造型別 (List<int>, List<string>) 獨立產生原生碼(參考型別共享實作)

泛型靜態成員的封閉型別隔離

關鍵規則:靜態成員在相同封閉型別的實例間共享,不同封閉型別互不共享。

public class Point<T> {
    public static T Width;
    public Point(T width) { Width = width; }
    public override string ToString() => Width.ToString();
}

// 測試
var p1 = new Point<int>(1);
var p2 = new Point<int>(2);
var p3 = new Point<long>(3);

Console.WriteLine(p1); // 2 (p2 覆蓋 p1 的靜態 Width)
Console.WriteLine(p2); // 2
Console.WriteLine(p3); // 3 (Point<long> 獨立靜態 Width)

Point<int> 與 Point<long> 是完全不同的型別,各自擁有獨立的靜態 Width 欄位。

泛型進階主題速覽

  • 泛型委派:Func<T, TResult>, Action<T> 等預設委派
  • 泛型介面:IEnumerable<T>, IComparer<T> 等
  • 泛型方法:型別參數在方法層級,如 T Max<T>(T a, T b) where T : IComparable<T>
  • 泛型約束:where T : class/struct/new()/base/interface 限制型別參數
  • 協變/逆變:out T (協變), in T (逆變) 用於介面/委派

總結

泛型透過 JIT 期具體化實現零成本抽象:編寫一次邏輯,獲得類型安全、效能最佳化、程式碼重用三重收益。理解其 IL 層面運作與靜態成員隔離規則,是進階 .NET 開發者的必修課。

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