.NET中值型別與引用型別以及值傳遞與引用傳遞
本章將和大家分享.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
版權宣告:如有雷同純屬巧合,如有侵權請及時聯絡本人修改,謝謝!!!