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ù)傳遞的時候,都稱為按值傳遞。
