C#裝箱拆箱機制詳解

????????在C#中,裝箱(Boxing)拆箱(Unboxing)?是值類型與引用類型之間轉換的核心機制。它們的實現直接影響程序的性能和類型安全。

一、裝箱(Boxing)

定義:

值類型轉換為引用類型(通常是object或接口類型)的過程

過程:

  1. 堆(Heap)中分配內存,用于存儲值類型的副本
  2. 棧(Stack)上的值類型數據復制到堆中
  3. 返回堆中新對象的引用

示例

int value = 1;
object boxed = value; //裝箱操作

常見場景

  • 將值類型添加到非泛型集合(如ArrayList)
  • 調用接受object參數的方法時傳遞值類型

特殊場景

1.Nullable類型(T?)的裝箱

  • 如果Nullable<T>的值為null,裝箱結果為null
  • 如果有值(如int?i = 1),則裝箱其基礎類型為(int

2.枚舉類型(Enum)的裝箱

枚舉值會被裝箱為底層類型(如int )的實例

性能影響:

  • 堆內存分配和復制操作會帶來性能開銷
  • 頻繁裝箱(如循環中)可能會導致內存壓力,觸發垃圾回收(GC)

二、拆箱

定義:

引用類型(已裝箱的值)轉換回原始值類型的過程,拆箱的本質是從堆中逐字節復制原始值類型數據到棧

過程:

  1. 檢查引用類型是否與目標值類型兼容(否則拋出InvalidCastException)
  2. 將堆中存儲的值復制到棧上的值類型變量中

示例

object boxed = 1;
int unboxed = (int)boxed; //拆箱操作

錯誤示例

object boxed = 1;
double d = (double)boxed; // 拋出 InvalidCastException

錯誤原因

類型兼容性:CLR(公共語言運行時)會驗證引用類型是否與目標值類型完全匹配,裝箱的是int,拆箱時目標類型必須也是int,否則拋出InvalidCastException

  • 拆箱的本質是從堆中?逐字節復制原始值類型數據?到棧
  • int?和?double?的內存布局不同:
  • int?是 4 字節整數(如?42?的二進制為?0x0000002A
  • double?是 8 字節浮點數(如?42.0?的二進制為?0x4045000000000000
  • CLR 無法直接將?int?的二進制數據當作?double?解析,必須顯式轉換

錯誤修正

  1. 拆箱到原始類型(int
  2. 顯式類型轉換(int?→?double

修正后代碼:

object boxed = 1;
int unboxedInt = (int)boxed;    // 正確拆箱到 int
double d = (double)unboxedInt;  // 再轉換為 double// 或者簡寫為:
double d = (int)boxed;          // 隱式轉換為 double

內存結構

托管堆中的對象:  
[對象頭] [同步塊索引] [int 數據 = 1]  
↑  
boxed 引用指向此處棧上的 unboxed 變量:  
[int 數據 = 1]

關鍵點

  • 必須顯式指定目標類型(強制類型轉換)
  • 拆箱失敗會拋出異常,需確保類型匹配
  • 拆箱后需要再次復制數據,仍有性能開銷

三、性能優化

1.使用泛型集合

如使用(List<T>)替代非泛型集合(ArrayList)避免裝箱

List<int> list = new List<int>(); // 無裝箱
list.Add(1);

2.利用接口泛型方法避免裝箱

例如,使用IEquatable<T>Equals(T other)方法,而不是object. Equals

3.注意ToString和格式化方法:

int i = 1;
Console.WriteLine(i.ToString()); // 避免裝箱(直接調用值類型的ToString)
Console.WriteLine($"{i}"); // 隱式調用 i.ToString(),避免裝箱

4.避免在循環或高頻代碼中裝箱/拆箱

5.使用isas安全檢查后再拆箱

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/72054.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/72054.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/72054.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MySQL 8.4 SQL 全攻略:所有知識點與實戰場景

一、引言 MySQL 作為一款廣泛使用的開源關系型數據庫管理系統&#xff0c;在數據存儲和管理領域占據著重要地位。MySQL 8.4 版本在性能、功能和安全性等方面都有了顯著的提升。本文將全面介紹 MySQL 8.4 中 SQL 的各種知識點&#xff0c;并結合實戰場景進行詳細講解&#xff0…

Qt監控系統遠程回放/錄像文件遠程下載/錄像文件打上水印/批量多線程極速下載

一、前言說明 在做這個功能的時候&#xff0c;著實費了點心思&#xff0c;好在之前做ffmpeg加密解密的時候&#xff0c;已經打通了極速加密保存文件&#xff0c;主要就是之前的類中新增了進度提示信號&#xff0c;比如當前已經處理到哪個position位置&#xff0c;發個信號出來…

超高速工業相機的應用

超高速工業相機一般安裝在機器流水線上代替人眼來做測量和判斷&#xff0c;通過數字圖像攝取目標轉換成圖像信號&#xff0c;傳送給專用的圖像處理系統。圖像處理系統對這些信號進行各種運算來抽取目標的特征&#xff0c;進而根據判別的結果來控制現場的設備動作。一般來說&…

Plugin ‘mysql_native_password‘ is not loaded`

Plugin ‘mysql_native_password’ is not loaded mysql_native_password介紹1. 使用默認的認證插件2. 修改 my.cnf 或 my.ini 配置文件3. 加載插件&#xff08;如果確實沒有加載&#xff09;4. 重新安裝或檢查 MySQL 版本 遇到錯誤 ERROR 1524 (HY000): Plugin mysql_nativ…

蒼穹外賣-阿里云OSS文件上傳

蒼穹外賣-阿里云OSS文件上傳 一、阿里云OSS簡介**獲取AccessKey**獲取enpoint 二、代碼實現1 引入依賴2 定義OSS相關配置2.1 application-dev.yml2.2 application.yml 3 讀取OSS配置3.1 AliOssProperties 4 生成OSS工具類對象4.1 AliOssUtil4.2 OssConfiguration2.5 CommonCont…

【工具】前端 js 判斷當前日期是否在當前自然周內

【工具】前端 js 判斷當前日期是否在當前自然周內 function isCurrentNaturalWeek(targetDate) {const today new Date();const dayOfWeek today.getDay(); // 0&#xff08;周日&#xff09;到6&#xff08;周六&#xff09;// 計算本周一的日期&#xff08;自然周從周一開…

【操作系統】處理機調度

處理機調度 一、調度的概念、層次1.1 三個層次1.2 七狀態模型 二、調度算法的評價指標2.1 CPU利用率2.2 系統吞吐率2.3 周轉時間2.4 等待時間2.5 響應時間 三、進程調度&#xff08;低級調度&#xff09;的時機3.1 需要進程調度的情況3.2 不能進程調度的情況3.3 閑逛進程 四、進…

SpringBoot 使用 spring.profiles.active 來區分不同環境配置

很多時候&#xff0c;我們項目在開發環境和生產環境的配置是不一樣的&#xff0c;例如&#xff0c;數據庫配置&#xff0c;在開發的時候&#xff0c;我們一般用測試數據庫&#xff0c;而在生產環境&#xff0c;我們要用生產數據庫&#xff0c;這時候&#xff0c;我們可以利用 p…

怎么進行mysql的優化?

MySQL 的優化是一個系統性的工作&#xff0c;涉及多個層面&#xff0c;包括查詢優化、索引優化、配置優化、架構優化等。以下是一些常見的 MySQL 優化方法&#xff1a; 查詢優化 避免全表掃描&#xff1a;確保查詢能夠使用索引&#xff0c;避免 SELECT *&#xff0c;只選擇需要…

談談 Node.js 中的模塊系統,CommonJS 和 ES Modules 的區別是什么?

Node.js 模塊系統&#xff1a;CommonJS 和 ES Modules 核心差異與實戰指南 一、模塊系統基礎概念 **CommonJS (CJS)**? 是 Node.js 傳統模塊系統&#xff0c;采用同步加載方式&#xff0c;典型特征&#xff1a; // 導出 module.exports { name: cjs }; // 或 exports.nam…

【HarmonyOS Next】 鴻蒙應用useNormalizedOHMUrl詳解

【HarmonyOS Next】 鴻蒙應用useNormalizedOHMUrl詳解 一、useNormalizedOHMUrl是什么? useNormalizedOHMUrl指的是是否使用標準化OHMUrl拼接。 在開發過程中&#xff0c;需要根據不同的環境或配置動態生成 URL。例如&#xff0c;在加載一些遠程模塊或者資源時&#xff0c;…

wav格式的音頻壓縮,WAV 轉 MP3 VBR 體積縮減比為 13.5%、多個 MP3 格式音頻合并為一個、文件夾存在則刪除重建,不存在則直接建立

&#x1f947; 版權: 本文由【墨理學AI】原創首發、各位讀者大大、敬請查閱、感謝三連 &#x1f389; 聲明: 作為全網 AI 領域 干貨最多的博主之一&#xff0c;?? 不負光陰不負卿 ?? 文章目錄 問題一&#xff1a;wav格式的音頻壓縮為哪些格式&#xff0c;網絡傳輸給用戶播放…

MFC線程

創建線程 HANDLE m_hThread; m_hThread CreateThread(NULL, 0, save_snapshot, (LPVOID)this, 0, &iThreadId);開啟線程循環等待 DWORD WINAPI save_snapshot(LPVOID pVoid) {while (true){//持續循環等待事件到達。接收到事件信號后才進入if。if (::WaitForSingleObjec…

賦能農業數字化轉型 雛森科技助力“聚農拼”平臺建設

賦能農業數字化轉型&#xff0c;雛森科技助力“聚農拼”平臺建設 在數字化浪潮席卷各行業的今天&#xff0c;農業領域也在積極探索轉型升級之路。中農集團一直以“根植大地&#xff0c;服務三農”為核心&#xff0c;以“鄉村振興&#xff0c;農民增收”為目標&#xff0c;及時…

千峰React:Hooks(上)

什么是Hooks ref引用值 普通變量的改變一般是不好觸發函數組件的渲染的&#xff0c;如果想讓一般的數據也可以得到狀態的保存&#xff0c;可以使用ref import { useState ,useRef} from reactfunction App() {const [count, setCount] useState(0)let num useRef(0)const h…

Ubuntu20.04安裝Redis

1.切換到root用戶 如果沒有切換到root用戶的&#xff0c;切換到root用戶。 2.使用 apt install redis 安裝redis 遇到y/n直接y即可。 redis安裝好之后就自動啟動起來了&#xff0c;因此我們可以通過netstat -anp | grep redis命令來查看是否安裝成功。 6379是Redis的默認端…

鴻蒙-AVPlayer

compileVersion 5.0.2&#xff08;14&#xff09; 音頻播放 import media from ohos.multimedia.media; import common from ohos.app.ability.common; import { BusinessError } from ohos.base;Entry Component struct AudioPlayer {private avPlayer: media.AVPlayer | nu…

機器學習數學通關指南——泰勒公式

前言 本文隸屬于專欄《機器學習數學通關指南》&#xff0c;該專欄為筆者原創&#xff0c;引用請注明來源&#xff0c;不足和錯誤之處請在評論區幫忙指出&#xff0c;謝謝&#xff01; 本專欄目錄結構和參考文獻請見《機器學習數學通關指南》 正文 一句話總結 泰勒公式是用多…

游戲引擎學習第124天

倉庫:https://gitee.com/mrxiao_com/2d_game_3 回顧/復習 今天是繼續完善和調試多線程的任務隊列。之前的幾天&#xff0c;我們已經介紹了多線程的一些基礎知識&#xff0c;包括如何創建工作隊列以及如何在線程中處理任務。今天&#xff0c;重點是解決那些我們之前沒有注意到…

在MacOS上打造本地部署的大模型知識庫(一)

一、在MacOS上安裝Ollama docker run -d -p 3000:8080 --add-hosthost.docker.internal:host-gateway -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:main 最后停掉Docker的ollama&#xff0c;就能在webui中加載llama模…