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

C# 裝箱與拆箱深度解析:IL 層面觀察與效能影響

     編輯:C# 入門

類型系統基礎

  • 值型別:int、struct、enum。儲存於堆疊,不可為 null,傳值語意。
  • 參考型別:class、interface、delegate、array。變數存參考,物件在堆積,可為 null。
  • 所有型別隱性繼承 System.Object (單根繼承)。

裝箱:值型別 → 參考型別

double val = 77.77;
object boxed = val; // 隱性裝箱

IL 指令:box [mscorlib]System.Double

執行期動作:

  1. 在 Managed Heap 配置記憶體 (大小 = 值型別大小 + 物件頭部)。
  2. 將值位元複製至新物件。
  3. 回傳新物件參考 (存入 boxed)。

拆箱:參考型別 → 值型別

double unboxed = (double)boxed; // 必須顯式轉型

IL 指令:unbox [mscorlib]System.Double + ldind.r8 (載入值)。

執行期動作:

  1. 檢查物件型別是否為 System.Double (否則擲回 InvalidCastException)。
  2. 取得物件內資料位址。
  3. 複製值至堆疊區域變數。

效能與記憶體影響

  • 配置開銷:每次裝箱在 Heap 配置新物件,頻繁裝箱 (如迴圈中 ArrayList.Add(i)) 產生大量短命物件,觸發 Gen 0 GC。
  • 複製開銷:值型別大小越大,複製成本越高。
  • 解決方案:
    — 使用泛型集合 List<T> 避免裝箱。
    — 介面參數改用泛型約束 where T : struct。
    — 必要時用 ref/out 傳遞值型別避免複製。

常見陷阱

ArrayList list = new ArrayList();
for (int i = 0; i < 10000; i++) list.Add(i); // 10000 次裝箱!

// 正確做法
List list = new List();
for (int i = 0; i < 10000; i++) list.Add(i); // 零裝箱

另一陷阱:呼叫值型別的 GetHashCode/Equals/ToString 會隱性裝箱,覆寫這些方法可減少裝箱。

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