值型別包括結構和列舉,引用型別包括了類,介面,委託等。還有一種特殊的值型別稱之為簡單型別。比如byte,int等,這些簡單型別實際是bcl基類庫的別名。
比如,宣告乙個型別int型別,實際上宣告的是system.int32結構型別。因此在int32型別中定義的方法或屬性都可以在int型別上使用。 比如123.equals(2).
通過msil**可以看到所有的值型別都隱式的繼承自system.valuetype(本身是乙個類型別)。system.valuetype型別和所有引用型別都繼承自system.object基類。
因為結構隱式的繼承了system.vauletype,所有結構不支援繼承(c#不支援多繼承。)
結構的乙個特性:呼叫結構上的方法之前,需要對其所有的字段複製,編譯器隱式的為構造型別建立無參的建構函式,在這個建構函式中會對結構成員進行初始化,所以在結構不允許定義無參的建構函式。
public struct a()}
通過隱式宣告建立乙個a型別變數
a a1=new a()console.writeline()
new操作符只是呼叫了a結構的預設函式,根據函式去初始化a結構的所有字段,並不分配記憶體和建立例項。
針對下面的情況
cosnole.writeline((new a()).x)
這種情況,通過misl觀察會建立乙個臨時變數,然後使用結構的預設建構函式對此臨時變數進行初始化。
new操作符建立引用型別例項的時候,該引用型別的變數會被分配到執行緒棧上,實際儲存了位於堆上的引用型別的例項的記憶體位址。變數本身不包含任何型別所定義的資料。
如果僅僅宣告乙個變數但是不使用new操作符,由於在堆上還沒有建立型別的例項,因此變數值為null。意思是不指向任何物件(堆上的物件的例項)。
結構屬於自定義的值型別,不能用==來判斷是否相等要用equals()方法。當使用==的時候比較的實際是判斷他們是否指向同乙個物件。而這裡並不是同乙個物件,而是物件所含的值相同。
string是引用型別,執行下面**
string a="1"string b="1"
if(a==b)
a,b不是執行同一物件所以條件為false,string是不可變型別。
個人記憶,值型別一般說的時候不牽扯到記憶體位址,主要是比較值,,引用型別牽扯到記憶體位址,這裡我把這個記憶體位址稱之為箱。
值型別需要乙個記憶體位址的引用來轉換成引用型別所以稱之為裝箱(加了個引用位址)。相反的引用型別轉成值型別就是拆箱了。(以上是個人記憶方法非官方語言解釋)
拆箱是將乙個已裝箱的引用型別轉換為值型別。拆箱操作需要兩步,1,獲取已經裝箱的物件的位址。2,將值從堆上的物件中複製到堆疊上的值變數中。
以為拆箱和裝箱反覆在堆上操作所以,盡量避免沒意義的裝箱拆箱操作。
《.net之美》讀書筆記
C 值型別和引用型別
c 資料型別 值型別,引用型別 概念 值型別直接儲存其值,引用型別儲存對值的引用 這兩種型別儲存在記憶體的不同地方 值型別儲存在堆疊中,引用型別儲存在託管堆上。乙個引用型別的例子,如圖 上圖中,只有乙個user物件,u1和u2都指向包含該物件的記憶體位置 執行結果 在c 中,基本資料型別如bool和...
c 值型別和引用型別
今天我們來學習一下什麼是值型別和引用型別。1.值型別的值存在棧上,引用型別棧上存的是位址,值在堆上 2.將乙個值型別變數賦給另乙個值型別變數時,將複製包含的值。引用型別變數的賦值只複製對物件的引用,而不複製物件本身。3.裝箱是將值型別轉換為引用型別,拆箱是將引用型別轉換為值型別,利用裝箱和拆箱功能,...
C 值型別和引用型別
型別被分為兩種 值型別 整數,bool,struct 建構函式 char 字元 小數 引用型別 string 陣列 自定義的類,內建的類,物件.兩者在記憶體中的儲存方式 值型別 只需要一段單獨的記憶體,用於儲存實際的資料,單獨定義的時候放在棧中 引用型別 需要兩段記憶體 第一段儲存實際的資料,它總是...