實值型別和參考型別

來源:互聯網
上載者:User

標籤:泛型   cells   數組   特殊   也有   body   回收   並且   int   

1.實值型別(ValueType)

實值型別包括:數實值型別,結構體,bool型,使用者定義的結構體,枚舉,可空類型。

實值型別的變數直接儲存資料,分配在託管棧中。變數會在建立它們的方法返回時自動釋放,例如在一個方法中聲明Char型的變數name=’C’,當執行個體化它的方法結束時,name變數在棧上佔用的記憶體就會自動釋放

C#的所有實值型別均隱式派生自System.ValueType。

結構體:struct(直接派生於System.ValueType)。
數實值型別:整型,sbyte(System.SByte的別 名),short(System.Int16),int(System.Int32),long(System.Int64),byte(System.Byte),ushort(System.UInt16),uint(System.UInt32),ulong(System.UInt64),char(System.Char)。
浮點型:float(System.Single),double(System.Double)。
財務計算的高精度decimal型:decimal(System.Decimal)。 
bool型:bool(System.Boolean的別名)。
使用者定義的結構體(派生於System.ValueType)。 
枚舉:enum(派生於System.Enum)。

可空類型(派生於System.Nullable<T>泛型結構體,T?實際上是System.Nullable<T>的別名

 

2.參考型別(ReferenceType)

參考型別包括:數組,使用者定義的類、介面、委託,object,字串,null類型,類。

參考型別的變數持有的是資料的引用,資料存放區在資料堆,分配在託管堆中,變數並不會在建立它們的方法結束時釋放記憶體,它們所佔用的記憶體會被CLR中的記憶體回收機制釋放。 

數組(派生於System.Array) 
使用者需定義以下類型: 
類:class(派生於System.Object); 
介面:interface(介面不是一個“東西”,所以不存在派生於何處的問題。介面只是表示一種contract約定[contract])。
委託:delegate(派生於System.Delegate)。 
object(System.Object的別名); 
字串:string(System.String的別名)。

 

3.實值型別與參考型別區別:

 

實值型別

參考型別

儲存方式

直接儲存資料本身

儲存的是資料的引用,資料存放區在資料堆中

記憶體配置

分配在棧中的

分配在堆中

效率

效率高,不需要地址轉換

效率較低,需要進行地址轉換

記憶體回收

使用完後立即回收

使用完後不立即回收,而是交給GC處理回收

賦值操作

建立一個新對象

建立一個引用

類型擴充

不易擴充,所有實值型別都是密封(seal)的,所以無法派生出新的實值型別

具有多態的特性方便擴充

執行個體分配

通常是線上程棧上分配的(靜態分配),但是在某些情形下可以儲存在堆中

總是在進程堆中分配(動態分配)

 

實值型別和參考型別樹形結構:

 

註:給參數加了fef(out)後,參數是引用傳遞,這時候傳遞的是棧地址(指標,引用),否則就是正常的值傳遞---棧未經處理資料的拷貝。

 4.記憶體配置

實值型別的執行個體經常會儲存在棧上的。但是也有特殊情況。如果某個類的執行個體有個實值型別的欄位,那麼實際上該欄位會和類執行個體儲存在同一個地方,即堆中。不過參考型別的對象總是儲存在堆中。如果一個結構的欄位是參考型別,那麼只有引用本身是和結構執行個體儲存在一起的(在棧或堆上,視情況而定)。

參考型別在棧中儲存一個引用,其實際的儲存位置位於託管堆。簡稱參考型別部署在託管推上。實值型別總是分配在它聲明的地方:作為欄位時,跟隨其所屬的變數(執行個體)儲存;作為局部變數時,儲存在棧上。實值型別在記憶體管理方面具有更好的效率,並且不支援多態,適合用做儲存資料的載體;參考型別支援多態,適合用於定義 應用程式的行為。 

註:堆棧(stack)是一種後進先出的資料結構。在記憶體中,變數會被分配在堆棧上來進行操作。堆(heap)是用於為類型執行個體(對象)分配空間的記憶體地區,在堆上建立一個對象,會將對象的地址傳給堆棧上的變數(反過來叫變數指向此對象,或者變數引用此對象)。

 5.裝箱和拆箱

1)裝箱就是將一個實值型別轉換成等值的參考型別

在堆上為新產生的對象(該對象包含資料,對象本身沒有名稱)分配記憶體。

將堆棧上實值型別變數的值拷貝到堆上的對象中。

將堆上建立的對象的地址返回給參考型別變數(從程式員角度看,這個變數的名稱就好像堆上對象的名稱一樣)。

2)拆箱就是將一個參考型別轉換成等值的實值型別

將參考型別變數堆上的值拷貝到棧上面。

總結

實值型別和參考型別理解透徹後,我們知道C#裡面是值傳遞,但是有些變數是參考型別的,在傳遞和拷貝時需要特別注意。方法傳遞參數時加上ref(out),為引用傳遞參數。

值傳遞僅僅傳遞的是值,不影響原始值。
引用傳遞,傳遞的是記憶體位址,修改後會改變記憶體位址對應儲存的值。

 

實值型別和參考型別

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.