值型別:宣告乙個值型別變數,會在棧上分配乙個空間,空間裡儲存的就是變數的值
引用型別:宣告乙個引用型別變數,會在棧中分配乙個空間,儲存乙個引用,這個引用指向了乙個託管堆。
值型別:struct,列舉,數值型別,bool型別
引用型別:陣列,類,介面,委託(delegate),object,string
可以看下下面的例子
public class person
public int age
}public class referenceandvalue
;person anders = new person ;
int age = zerocool.age;
zerocool.age = 22;
person guru = anders;
anders.name = "anders hejlsberg";
console.writeline("zerocool's age:\t", zerocool.age); //22
console.writeline("age's value:\t", age); //25
console.writeline("anders' name:\t", anders.name); //anders hejlsberg
console.writeline("guru' name:\t", guru.name); //anders hejlsberg
console.readkey();}}
**分析:
我們首先定義了乙個person類,包含2個屬性,age和name,其中age是值型別,name是string引用型別
然後初始化了2個person類,zerocool和anders,並賦值,然後再修改age和name
這個時候,由於值型別的特點,我們只是在棧上給zerocool.age分配了一段資源,和後來宣告的age是沒有任何關係的。所以age是不變的。
修改name則不一樣,因為是修改引用型別。name和anders.name是相關聯的,所以也會跟著變化。
所以也就會有後來的輸出結果。
再說說 裝箱 & 拆箱
裝箱發生在 值型別 往 引用型別 轉換
拆箱發生在 引用型別 往 值型別 轉換
將值型別轉換為引用型別,需要進行裝箱操作(boxing):
1、首先從託管堆中為新生成的引用物件分配記憶體。
2、然後將值型別的資料拷貝到剛剛分配的記憶體中。
3、返回託管堆中新分配物件的位址。
可以看出,進行一次裝箱要進行分配記憶體和拷貝資料這兩項比較影響效能的操作。
將引用內型轉換為值內型,需要進行拆箱操作(unboxing):
1、首先獲取託管堆中屬於值型別那部分欄位的位址,這一步是嚴格意義上的拆箱。
2、將引用物件中的值拷貝到位於執行緒堆疊上的值型別例項中。
經過這2步,可以認為是同boxing是互反操作。嚴格意義上的拆箱,並不影響效能,但伴隨這之後的拷貝資料的操作就會同boxing操作中一樣影響效能。
再舉個平時常用的例子
//當我們如下時:
for (int i = 0; i < arr.length; i++)
//我們更因該這樣:
int l = arr.length;
for (int i = 0; i < l; i++)
i 也可以通過過載函式來避免,通過泛型來避免裝箱(暫時還沒理解)
像console.writeline()這種方法,也很可能會涉及到裝箱等等操作
堆 棧 值型別 引用型別 裝箱 拆箱
一來是為了感受國外優秀技術社群知名博主的高質量文章,二來是為了複習對.net技術的基礎拾遺達到溫故知新的效果,最後也是為了鍛鍊一下自己的英文讀寫能力。因為是首次翻譯英文文章 哎,原諒我這個菜比,弱爆了!所以肯定會有很多問題 有些語句理解不透徹,翻譯出來也不通順,還請不吝賜教 也請各位園友多多指正,謝...
值型別和引用型別,裝箱和拆箱
c 中任何型別都是隱式繼承自 system.object 引用型別 分為兩大類,值型別和引用型別。值型別包括 簡單型別 int,float,double等 結構體,列舉 引用型別包括 自定義的類,字串,介面,陣列 區別 1.值型別儲存在棧中,自動釋放,比較高效 引用型別儲存在堆中,需要手動釋放 2....
值型別與引用型別區別and裝箱與拆箱
1.引用型別的內存在託管堆上分配的。new操作符會返回物件的記憶體位址。2.值型別比引用型別輕量級 值型別包含啥呢,結構和列舉 3.值型別是不能作為基類 4.gc不管值型別 5.引用型別沒有初始化時是null,即不指向任何的記憶體位址,如果使用會拋異常nullreference異常 值型別的初始值是...