本章將和大家分享.NET中值類型與引用類型以及值傳遞與引用傳遞。
一、值類型與引用類型
值類型:數值類型、結構體、bool類型、枚舉、可空類型(例如:int、double、bool、char、decimal、struct、enum)等等。
引用類型:數組、委托、接口、object、集合、字符串、用戶自定義的類等等。
存儲:
值類型的值是存儲在內存的棧當中。
引用類型的值是存儲在內存的堆當中。(引用類型同時也會在棧中開辟一塊空間,用於存放這個值在堆中的地址。)
示例圖如下所示:
二、裝箱與拆箱
裝箱:就是將值類型轉換為引用類型。
拆箱:就是將引用類型轉換為值類型。
看兩種類型是否發生了裝箱或者拆箱,前提是要看這兩種類型是否存在繼承關系。沒有繼承關系的一定不會發生拆箱或者裝箱,有繼承關系的才有可能發生拆箱或者裝箱。
示例:
using System; namespace ValueTypeAndReferenceType { class Program { static void Main(string[] args) { { int n = 9; object o = n; //裝箱 int m = (int)o; //拆箱 } //string和int沒有繼承關系,故沒有發生拆箱或裝箱 { string str = "123"; int n = Convert.ToInt32(str); } //int繼承IComparable,故此處是裝箱 { int n = 10; IComparable i = n; //裝箱 } } } }
拆箱和裝箱會影響程序的性能,故在程序開發過程中應盡量避免發生裝箱或者拆箱。
三、值傳遞與引用傳遞
值類型在復制的時候,傳遞的是這個值的本身。
引用類型在復制的時候,傳遞的是對這個對象的引用。
示例圖如下所示:
從即時窗口中可以很直觀的看出值傳遞和引用傳遞的區別。(此處用到了&)
字符串的不可變性:
從上圖中可以很直觀的看出字符串的不可變性,改變其中一個值另外一個不受影響。因為改變的時候如果內存中不存在這個新的字符串值它就會去重新開辟一塊內存空間存儲。
1、值類型按值傳遞
可以發現值類型按值傳遞時兩個變量在棧中的地址是不同的,故兩個變量的值互不影響。
運行結果如下所示:
2、值類型按引用傳遞
可以發現值類型按引用傳遞的時候兩個變量的棧地址是一樣的,故改變其中一個變量的值另外一個變量會跟着變。
運行結果如下所示:
3、引用類型按值傳遞
可以看出引用類型按值傳遞的時候,兩個變量在堆當中的地址是一樣的,故改變其中一個對象的屬性另外一個對象會受到影響。
運行結果如下所示:
還有一種情況是變量p2在Test方法內部被重新初始化了,如下所示:
可以發現此時兩個變量的棧地址和堆地址都不一樣,故兩個變量互不影響。
運行結果如下所示:
4、引用類型按引用傳遞
可以發現引用類型按引用傳遞的時候(加了ref),兩個變量的棧地址和堆地址都是一樣的,故兩個變量值改變時會互相影響。
運行結果如下所示:
同樣的還有一種情況是變量p2在Test方法內部被重新初始化了,如下所示:
從即時窗口中可以發現,當變量p2被重新初始化后變量p1的堆地址也跟着p2變化了,故此時改變其中一個變量的值則另外一個變量也會受到影響,這點和引用類型按值傳遞有很大不同。
運行結果如下所示:
至此本文就全部介紹完了,如果覺得對您有所啟發請記得點個贊哦!!!
此文由博主精心撰寫轉載請保留此原文鏈接:https://www.cnblogs.com/xyh9039/p/13700316.html
版權聲明:如有雷同純屬巧合,如有侵權請及時聯系本人修改,謝謝!!!