裝箱和拆箱、類型比較

来源:http://www.cnblogs.com/youyingchou/archive/2017/02/10/6386358.html
-Advertisement-
Play Games

最近在看CLR via C#,複習一下,看著老是忘,做個筆記。 裝箱和拆箱 1.裝箱,值類型向引用類型轉換: 在托管堆中分配記憶體,分配的記憶體量是類型各欄位所需的記憶體量+類型對象指針所需的記憶體量+同步塊索引所需的記憶體量。 值類型的欄位複製到分配好的記憶體中 返回對象地址,現在對象地址是對象引用 2.拆箱 ...


最近在看CLR via C#,複習一下,看著老是忘,做個筆記。

 

裝箱和拆箱

1.裝箱,值類型向引用類型轉換:

                      在托管堆中分配記憶體,分配的記憶體量是類型各欄位所需的記憶體量+類型對象指針所需的記憶體量+同步塊索引所需的記憶體量。

                      值類型的欄位複製到分配好的記憶體中

                      返回對象地址,現在對象地址是對象引用

2.拆箱,引用類型向值類型轉換:

                      獲取已裝箱類型中的未裝箱部分,也就是對象的原始值的各個欄位

                      複製欄位的值從堆中到棧中的值類型實例中

 

所以拆箱是不需要分配記憶體的,但是都要複製。

 

== Equals的比較

 

引用類型進行比較,==比較兩個參數的引用地址。調用equlas的時候,如果該類型或基類(除了object)沒有重寫object.equlas方法,則調用object.equlas方法,比較兩個類型的引用地址,否則則調用該類型或基類重寫的equlas方法(比如string)。

值類型進行比較,==比較兩個參數的值。調用equlas的時候,因為值類型的基類System.ValueType重寫了equlas,使比較的時候比較的兩個參數的值,所以也會比較兩個參數的值。

 

object a = new Test { a = 1 };
object b = new Test { a = 1 };

Console.WriteLine(a == b); //false 因為比較的是引用的地址,兩個引用類型的對象引用地址自然不同
Console.WriteLine(a.Equals(b));//false 因為Test類沒有重寫equlas,則調用的是Object.equals,而Object的equlas比較的是引用的地址

 

object c = 1;
object d = 1;

Console.WriteLine(c==d);//false 兩個參數都已經裝箱,成為引用類型,所以引用地址不同
Console.WriteLine(c.Equals(d));//true,值類型的基類System.ValueType重寫了equlas,使比較的時候比較的兩個參數的值

 

object e = "123";
object f = "123";

Console.WriteLine(e==f); //true  string類型做了優化,所以並沒有給f單獨分配記憶體,只是將已經分配好記憶體的"123"指向了f,所以引用地址相同
Console.WriteLine(e.Equals(f));//true  System.String 重寫了equlas,使比較的時候比較的兩個參數的值(不過這裡因為引用地址相同,所以有沒有重寫都是返回true)

 

object l = string.Copy(e.ToString());
Console.WriteLine(l == e); //false 直接copy,另外分配記憶體複製值進去,就和普通引用對象一樣,所以引用地址不同
Console.WriteLine(l.Equals(e));//true System.String 重寫了equlas,使比較的時候比較的兩個參數的值,所以引用地址不同但值相同也返回true

 

 

int h = 1;
int i = 1;


Console.WriteLine(h==i); //true 值類型==比較的兩個數的值
Console.WriteLine(h.Equals(i));//true ,值類型的基類System.ValueType重寫了equlas,使比較的時候比較的兩個參數的值

 

總結:

最終,對於值類型,==和equlas都比較值。對於引用類型,==比較引用地址,如果沒重寫Object.equlas方法,比較地址,重寫了,則調用重寫的方法。

 

ReferenceEquals

object的靜態類型方法,比較兩個參數的引用地址。和==操作運算符很像,但是==是可以被重載的。所以比較引用類型的引用地址時候用這個最好。

 

Equlas的重寫

1.判斷傳遞的值是否為null,如果為null,則返回false

2.判斷傳遞的值和this是否引用同一地址,如果同一地址,則返回true

3.判斷傳遞的值的類型和this的類型是否一致,類型不一致,則不可能相等,返回false

4.根據傳遞的值的欄位和this的欄位進行比較,只要有不一致,則返回false

5.調用基類的equlas,如果為true,則返回true,如果為false,則返回false。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 想要執行一次全局更新,發現屢次報錯: 提示的錯誤信息包含如下內容: 尋找解決方案未果。後來看到一個不相關的回答: ,腦洞大開想到可能是npm的modules文件夾下多出了一個npm debug.log的文件,導致查詢倉庫時把這個文件名也拿去查詢了。locate一下發現果真如此: 將這個文件刪掉後再次 ...
  • 說明 我在項目中根據需求需要用到WPF Dev CellTemplateSelector時,遇到不少坑。曾一度想要放棄使用模板轉換器,但又心有不甘,終於在不斷努力下,達到了需求的要求。所以寫下來和大家分享。如果有同樣困惑的人,可以少走些彎路。筆者第一次寫博客,文筆不好,還請見諒。 需求 需求很簡單, ...
  • windows7下麵安裝nfs客戶端命令(首先開啟windows客戶端mount掛載命令): windows7下麵安裝nfs客戶端命令(首先開啟windows客戶端mount掛載命令): 打開或關閉windows功能>nfs服務(勾選上)重啟 windows nfs共用有兩種方式分別是如下hanew ...
  • 上篇(.Net Standard擴展支持實例分享)介紹了OSS.Common的標準庫支持擴展,也列舉了可能遇到問題的解決方案。由於時間有限,同時.net standard暫時還沒有提供對DescriptionAttribute的支持,所以其中的轉化枚舉到字典列表的擴展當時按照第一種處理方式先行屏蔽, ...
  • 最近幾年想必大家一聽到哪裡有搶紅包可以搶,馬上會拿起手機點去~~~~然後問題來了。。。 如何控制在同一時間保證資料庫中扣減紅包餘額不會出錯。之前我們的做法是直接鎖程式,這樣子帶來的壞處就是等待時間太長,每當一個線程進去之後要經過以下幾個過程。 過程分別是 1. 查表 2. 校驗信息 3. 發送微信服 ...
  • 緣由 最近開發的小程式過程中需要涉及到XML相關操作,突然發現自己對於這知識點瞭解的太少,急需學習加強。剛好項目的時間也不是很緊急,自己就總結XML相關知識點。一個方面自己學習,一個方面也希望可以幫到新手。 XML系列目錄導航 本系列準備從以下幾個點來說明: 1. "XML簡介" 2. "C 讀取X ...
  • 前言 項目之前使用Eclipse導出的jar文件來做與Android交互,最近因為工作需要需使用Android Studio的aar文件,網上參考了部分文章,也結合自己的理解重新整理一下具體的方法,通過寫一個測試Demo來表述Android Studio創建aar的過程與及Unity如何使用aar文 ...
  • 為了實現保持登錄狀態,可以用cookie來解決這一問題 假設過期時間為30分鐘,校驗發生在伺服器,藉助過濾器,可以這樣寫 但是頁面直接跳轉了,也沒有一個提示,顯得不是很友好,可以這樣 但是,假如是ajax請求呢? ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...