深入理解值型別和引用型別,這是.net開發人員取得長期成功的關鍵,下面從記憶體布局角度詳細給大家說明一下值型別和引用型別:
值型別的記憶體結構:
引用型別的記憶體結構:
引用型別的例項比值型別的例項多了兩個附加的字段,syncblockindex和rtti(執行時型別資訊)指標,指向乙個方法表結構,所以描述為 methodtableptr和typeobjectptr都是可以的,〈clr via c#〉這本書的第一版標註的是methodtableptr,第二版標註的是typeobjectptr,這裡應該是jeffery認為 typeobjectptr更加準確。
另外,除object和valuetype型別以外,值型別不能繼承其他任何型別,同時也無法作為其他值型別的基類,所以一般情況下,也就無需方法表指標 了!需要呼叫呼叫從object或valuetype繼承的一些方法的時候,需要乙個方法表指標,這時就需要對值型別進行裝箱!
看乙個例子:
public struct a
}static void main(string args)
{a a=new a();
a.tostring();//這時不會發生裝箱,因為c#編譯器發現結構體a重寫了tostring方法,於是產生直接呼叫tostring的il指 令,而且不可能有型別繼承自結構體a,所以編譯器可以確定這裡不會有多型性的行為,於是就無須方法表指標,也無須裝箱!
a.gettype();//這裡會發生裝箱,因為結構體a本身沒有實現gettype方法,需要呼叫繼承的gettype方法,這時需要乙個方法表指標來訪問方法表,這時需要通過裝箱來獲得!
從編譯原理來看引用型別和值型別
看了好多書,研究了下值型別和引用型別,總是有種模稜兩可的感覺,這讓我萌發了,大眾角度主要是分析記憶體中的東西,而我準備從記憶體和編譯原理兩個方面來入手,本人先說明我沒學過編譯原理,但略讀了下,發現用這個來解釋更好。參考 程式設計編譯原理 這本書,我不知道vs ide的編譯工具是採用什麼編譯原理的,但...
引用型別和值型別
c 是一種型別安全的語言。每乙個變數都要求定義為乙個特定的型別,並且要求儲存在變數中的值只能是這種型別的值。變數既能儲存值型別,也可以儲存引用型別,還可以是指標。這一課將講述前兩種型別,關於指標的討論我們將在下一課中進行。下面是關於值型別和引用型別不同點的概論 如果乙個變數v儲存的是值型別,則它直接...
引用型別和值型別
c 中值型別和引用型別作為方法引數傳遞的時候其實都可以說是 值 的傳遞,只不過這裡的 值 指代的東西有所區別。當方法的引數為值型別時,方法傳遞的是值本身的值。當方法的引數為引用型別時,方法傳遞的則是應用型別的引用的位址,也就是引用型別位址在棧上的值。舉個引用型別作為引數傳遞的例子 static vo...