C 中值型別和引用型別

2022-03-07 23:20:58 字數 1915 閱讀 9914

本文將介紹c#型別系統中的值型別和引用型別,以及兩者之間的一些區別。同時,還會介紹一下裝箱和拆箱操作。

首先,我們看看在c#中哪些型別是值型別,哪些型別是引用型別。

值型別:

結構型別(struct)

列舉型別(enum)

引用型別:

變數的初始化中,都會有乙個預設值,在c#中,我們可以通過default關鍵字去檢視某個型別的預設值。

通過default(int)可以看到,int的預設值是0,default(bool)顯示布林型別的預設值是false。

對於所有的引用型別,預設值都會是null。

注意,這裡有個特殊的情況就是結構struct,如果對乙個結構進行default操作,我們將得到每個結構成員的初始值狀態。也就是說,值型別成員賦予值型別的預設值,引用型別成員賦予引用型別的預設值。

下面,我們通過乙個簡單的例子看看。假設有乙個point型別,有x和y兩個座標成員。

同樣是下面一段**

point p1 = new point(5,9

);point p2 = p1;

如果point型別是通過結構struct實現,那麼p2將會是p1的乙個副本,也就是說任何乙個的修改都不會影響另外乙個;如果point型別是通過類class實現,那麼p2和p1的引用值將會指向同乙個物件。

為了進一步了解值型別和引用型別,我們需要介紹一下棧和堆這兩個基本概念。

當我們在32位系統上執行乙個程式的時候,這個程式就會有乙個4gb的程序執行空間。我們所要討論的棧和堆就存放在這個4gb的空間中。

在c#中,棧(stack)是指呼叫棧(call stack);堆(heap)是指託管堆,由.net垃圾收集器自動管理。

這裡就不對棧和堆進行詳細的分析了,只是舉乙個簡單的例子來大致描述棧和堆的工作原理。

從圖中可以看到,區域性變數在棧上的變化(入棧),當函式執行結束後,棧上的空間將會被清理;但是我們在堆上分配的空間始終從在,只能等待gc去幫我們清理不會被引用到的空間。

介紹過棧和堆之後,下面我們看看值型別和引用型別是怎麼存放的。

對於值型別的變數,這個變數本身就代表這個值型別的值;但是,對於引用型別的變數,這個引用型別的例項是在託管堆上分配的空間,而這個變數本身只是代表乙個指向託管堆例項的引用(指標)

所以這裡,我們可以對值型別和引用型別變數的儲存有兩個概括:

注意:根據上面第二點概括,可以得到"值型別一定儲存在棧中"這個說法是錯誤的。例如,我們有乙個student類,在這個類中的age屬性是乙個值型別,但是這個值型別是儲存在student類例項的空間中,也就是在堆上。

class

student

public

int age

}

由於c#中所有的資料型別都是由基類system.object繼承而來的,所以值型別和引用型別的值可以通過顯式(或隱式)操作相互轉換。

這裡,可以將裝箱和拆箱描述為:

其實,在裝箱和拆箱的過程中都對應一系列的轉換,這裡就通過下圖表示了。

在值型別進行裝箱時,生成的是全新的引用物件,這會有時間損耗,也就是造成效率降低。所以在c# 2.0中就引入了泛型來減少裝箱操作和拆箱操作消耗。

本文介紹了c#中的值型別和引用型別,以及棧和堆的基本概念。然後分析了值型別和引用型別在棧和堆中的存放。

同時,我們也了解到了:

C 中值型別和引用型別

概念 1.值型別 資料儲存在記憶體的堆疊中,從堆疊中可以快速地訪問這些資料,因此,值型別表示實際的資料。2.引用型別 表示指向儲存在記憶體堆中的資料的指標或引用 包括類 介面 陣列和字串 c 中定義的值型別包括原型別 sbyte byte short ushort int uint long ulo...

c 中值型別和引用型別

在c 中有兩種型別的資料,一種是值型別資料,一種是引用型別資料。在編碼的時候區分這兩種型別資料,可以避免一些細小的編碼錯誤。首先說說什麼型別是值型別,例如 int float bool之類的基礎型別,以及用struct定義的型別,如 datetime。除此外,如string,陣列,以及用class定...

c 中值型別與引用型別

c 的值型別包括 結構體 數值型別,bool型,使用者定義的結構體 列舉,可空型別。c 的引用型別包括 陣列,使用者定義的類 介面 委託,object,字串。陣列的元素,不管是引用型別還是值型別,都儲存在託管堆上。引用型別在棧中儲存乙個引用,其實際的儲存位置位於託管堆。為了方便,這裡將引用型別部署在...