首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C# 裝箱拆箱深度解析:為什麼修改原值類型不影響已裝箱對象

     編輯:程式設計綜合問答

代碼現象

int i = 2008;
object obj = i;  // 裝箱
Console.WriteLine($"1、i={i}, obj={obj}");  // 2008, 2008

i = 927;  // 修改原值類型
Console.WriteLine($"2、i={i}, obj={obj}");  // 927, 2008  ← obj 未變!

核心原理:裝箱創建副本

  1. object obj = i; 觸發**裝箱**:在堆上分配新對象,將 i 的值(2008)**複製**進去。obj 指向這個新對象。
  2. i = 927; 修改棧上變量 i 的值,**與堆上對象無關**。
  3. 因此 obj 仍保持裝箱時的值 2008。

記憶模型圖解

執行 object obj = i; 後:
棧:i → 2008
堆:obj → [Object Header][2008]  (獨立副本)

執行 i = 927; 後:
棧:i → 927
堆:obj → [Object Header][2008]  (未變)

延伸:引用類型賦值也同理

object obj1 = 100;  // 裝箱
object obj2 = obj1; // 引用賦值,指向同一堆對象
obj2 = 200;         // 再次裝箱!obj2 指向新對象[200],obj1 仍指向[100]
Console.WriteLine(obj1); // 100

obj2 = 200 不是修改原對象,而是觸發**新裝箱**,obj2 指向新對象。

關鍵結論

  • **值類型裝箱 = 值複製到堆**;原值類型與裝箱對象**完全獨立**。
  • **引用類型賦值 = 引用複製**;但對變量重新賦值(=)會改變引用指向,不影響原對象。
  • 真正的「共享狀態」需用 class 封裝字段,或使用 ref/out 傳遞值類型地址。

面試/考試陷阱提示

常見問題:「裝箱後修改原值,裝箱對象變嗎?」→ **不變**。

「object a=1; object b=a; b=2; a 是多少?」→ **1**(b=2 觸發新裝箱)。

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