值型別和引用型別

2021-06-01 10:12:17 字數 3247 閱讀 5588

變數、常量和杖舉

常量:用來代替乙個數或字串的名稱,我們可以在初始化時定義。在變數前增加關鍵字「const」,就可以把這個變數設定為常量。

語法如下:

訪問修飾符 const 資料型別 常量名 = 值

注:常量在使用過程中是不能被修改的,如果要修改乙個常量的話程式會發生錯誤。

杖舉:事先考慮到某一變數可能取得值,盡量用自然語言中含義清楚的單詞來表示它的每乙個值。用杖舉得方法定義的型別稱為杖舉型別。杖舉是乙個被命名的整型常數的集合。定義乙個杖舉得關鍵字是「enum」,語法如下:

public enum 杖舉名

注:如果杖舉沒有初始化,即省掉「=整型常數」時,則從第乙個識別符號開始,順次賦給識別符號0,1,2,...。但當杖舉中得某個成員賦值後,其後的成員按依次加1的規則確定其值。例如:

public enum ***

杖舉的第乙個元素「男」顯式的賦值是「1」,那第二個元素「女」對應的數值就自動的變成2了。

還可以對杖舉進行型別轉換,可以用int型別來表示乙個杖舉,如下:

reader reader = new reader();

reader.getweek=((weekday)2);

還可以反過來,由杖舉轉換為數字,如下:

int k = (int) weekday.女;

再有,我們也可以用字串來代替杖舉,如下:

string booktype = ;

console.writeline("我喜歡的型別是",booktype[2]);

使用杖舉得優勢如下:

◇ 杖舉是強型別的,可以避免型別錯誤,在輸入了與宣告不一致的杖舉值的時候,會產生編譯錯誤。

◇ 杖舉使**更清晰,允許用描述性的名稱表示整數值,而不是用含義模糊的數來表示,增加了程式的可讀性和可維護性。

◇ 杖舉使**更易於鍵入。在給杖舉型別的實力賦值時,vs.net ide 會通過智慧型提示符(「.」)彈出乙個包含可接受的列表框,減少了按鍵次數,並能讓我們回憶起可能的值。

類和結構

結構:將乙個物件作為內建的乙個資料型別以加快分配。定義結構的關鍵字是struct,語法如下:

訪問修飾符 struct 結構名   

注:結構的定義和類很相似,可以有欄位,可以有方法。但是當在結構中定義欄位的時候,字段不能賦值。

結構的使用:在不使用結構的屬性時可以不用new,直接使用,但是在定義結構的時候,必須為結構的成員賦初值,然後直接用名字就可以了。如下:

readerstruct reads;

reads._sge = 13;

reads._name = "張三";

但是如果使用結構中的屬性等成員,必須要先把結構用new例項化才能使用。如下:

readerstruct reads = new readerstruct();

reads.age=13;

reads.name="張三";

在例項化類的時候,其實是呼叫類的構造方法。結構和類相似,也有它自己的構造方法。c#給結構提供了乙個無參構造方法,但是和類不一樣的是結構中不能包含顯式的無參構造方法,那是因為clr並不要求結構必須定義構造方法。實際上c#編譯器也不會為結構產生預設的無參構造方法。但clr允許我們為結構定義構造方法。當我們使用構造方法時,只有顯式呼叫時構造方法才會被執行。用new來建立乙個結構時,只是呼叫的他得構造方法。如果不適用new來建立,那麼結構的字段都會保持為0,因為在呼叫構造方法之前系統為該物件分配的記憶體總是被設定為0。由於結構是引用型別,所以結構的值總不能為null。

注意:不能給結構顯式定義乙個無參構造方法。我們在使用結構的構造方法時,必須是有參的構造方法,而且在構造方法中,必須把結構中所有的字段賦值。

結構和類的區別:

結構                                           類

值型別,在堆疊上分配位址                       引用型別,在堆上分配位址

沒有 預設的構造方法,但是可以新增構造方法       有預設的構造方法

沒有析構函式                                  有析構函式

不能給字段賦值                                可以給字段賦值

不能有 protected 修飾符                       可以使用

不能新增無參構造方法                           可以新增

不能被繼承                                    能被繼承

注意:結構的儲存位置是在堆載上而類的儲存位置是在堆上,堆載的空間有限,所以表示如點,矩形和顏色這樣的輕量物件的時候,我們可以選擇結構來實現,結構是值型別,開銷小,效率高,主要用於組織資料。對於大量的邏輯的物件,建立類要比建立結構要好。

值型別和引用型別

值型別:c#的值型別派生於system.valuetye基類。當建立乙個值型別的時候,都會在堆疊上開闢一塊新的記憶體空間來儲存值,當修改這個值的時候其實是修改它所在的記憶體空間的值。這就相當於建立了乙個物件的副本,也就是複製了某個物件。一般來說值型別包含基本的資料型別,結構,杖舉等。

引用型別:c#的引用型別派生於system.object基類。當建立乙個引用型別的時候,在堆疊上分配一快空間,用來儲存引用型別(類)物件,當給這個引用型別賦值的時候,在堆疊上劃分一塊空間用來儲存類在這個堆上的位址(當給這個位址起名字的時候就是所定義的變數名)。其實我們可以這樣認為,在給引用型別(如類)賦值的時候,其實賦值的是引用型別的位址。當類作為引數的時候,當引數被修改的時候,會修改類成員的值。因為他們指向同一位址內容。

其實值型別和引用型別的最主要的區別就是儲存方式的不同。

裝箱和拆箱

裝箱:由值型別轉換為引用型別。

拆箱:由引用型別轉換為值型別。

例如:將乙個整型(int)賦值給乙個object型別的變數:

int i = 123;

object o = i;

注:第2句**講值型別的資料「123」放到了乙個object型別的變數o中,而o是乙個引用型別變數,其引用的物件儲存在堆中。clr講值型別的資料「包裹」到乙個匿名的物件中,並將此物件中引用放在object型別的變數o中,這個過程稱為「裝箱」。

拆箱的過程如下:

int i =123;

object o = i;

int j =(int)o

注意:裝箱操作可以隱式進行但拆箱操作必須是顯示的。拆箱過程分為兩步:1,檢查這個物件例項,看它是否為給定的值型別的裝箱值。2,把這個例項的值拷貝給值型別的變數。  在拆箱的時候要注意型別的轉換,所定義的值型別要與引用型別的資料型別一致,否則會發生型別轉換的異常。

引用型別和值型別

c 是一種型別安全的語言。每乙個變數都要求定義為乙個特定的型別,並且要求儲存在變數中的值只能是這種型別的值。變數既能儲存值型別,也可以儲存引用型別,還可以是指標。這一課將講述前兩種型別,關於指標的討論我們將在下一課中進行。下面是關於值型別和引用型別不同點的概論 如果乙個變數v儲存的是值型別,則它直接...

引用型別和值型別

c 中值型別和引用型別作為方法引數傳遞的時候其實都可以說是 值 的傳遞,只不過這裡的 值 指代的東西有所區別。當方法的引數為值型別時,方法傳遞的是值本身的值。當方法的引數為引用型別時,方法傳遞的則是應用型別的引用的位址,也就是引用型別位址在棧上的值。舉個引用型別作為引數傳遞的例子 static vo...

值型別和引用型別

為了更好地說明兩種型別之間的區別,借用如下的 來說明 值型別引用型別 記憶體分配地點 分配在棧中 分配在堆中 效率效率高,不需要位址轉換 效率低,需要進行位址轉換 記憶體 使用完後,立即 使用完後,不是立即 等待gc 賦值操作 進行複製,建立乙個同值新物件 只是對原有物件的引用 函式引數與返回值 是...