值類型,引用類型(C#)

1.值類型與引用類型的區(qū)別:

CLR支持兩只類型:引用類型值類型。這是.NET語言的基礎(chǔ)和關(guān)鍵,他們從類型定義、實(shí)例創(chuàng)建、參數(shù)傳遞,到內(nèi)存分配都有所不同。


下圖清晰了展示了.NET中類型分類,值類型主要是一些簡單的、基礎(chǔ)的數(shù)據(jù)類型,引用類型主要用于更豐富的、復(fù)雜的、復(fù)合的數(shù)據(jù)類型。


值類型和引用類型最根源的區(qū)別就是其內(nèi)存分配的差異,在這之前首先要理解CLR的內(nèi)存中兩個重要的概念:

Stack 棧:線程棧,由操作系統(tǒng)管理,存放值類型、引用類型變量(就是引用對象在托管堆上的地址)。棧是基于線程的,也就是說一個線程會包含一個線程棧,線程棧中的值類型在對象作用域結(jié)束后會被清理,效率很高。

GC Heap托管堆:進(jìn)程初始化后在進(jìn)程地址空間上劃分的內(nèi)存空間,存儲.NET運(yùn)行過程中的對象,所有的引用類型都分配在托管堆上,托管堆上分配的對象是由GC來管理和釋放的。托管堆是基于進(jìn)程的,當(dāng)然托管堆內(nèi)部還有其他更為復(fù)雜的結(jié)構(gòu),有興趣的可以深入了解。

結(jié)合下圖理解,變量a及其值3都是存儲在棧上面。變量b在棧上存儲,其值指向字符串“123”的托管堆對象地址(字符串是引用類型,字符串對象是存儲在托管堆上面。字符串是一個特殊的引用類型,后面文章會專門探討)”


值類型一直都存儲在棧上面嗎?所有的引用類型都存儲在托管堆上面嗎?

1.單獨(dú)的值類型變量,如局部值類型變量都是存儲在棧上面的;

2.當(dāng)值類型是自定義class的一個字段、屬性時,它隨引用類型存儲在托管堆上,此時她是引用類型的一部分;

4.所有的引用類型肯定都是存放在托管堆上的。

5.還有一種情況,同上面題目12,結(jié)構(gòu)體(值類型)中定義引用類型字段,結(jié)構(gòu)體是存儲在棧上,其引用變量字段只存儲內(nèi)存地址,指向堆中的引用實(shí)例。

對象的傳遞

將值類型的變量賦值給另一個變量(或者作為參數(shù)傳遞),會執(zhí)行一次值復(fù)制。將引用類型的變量賦值給另一個引用類型的變量,它復(fù)制的值是引用對象的內(nèi)存地址,因此賦值后就會多一個變量指向同一個引用對象實(shí)例。當(dāng)把對象作為參數(shù)傳遞的時候,都稱為按值傳遞。


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容