淺談C#類型系統(tǒng)
我們先簡單回顧一下C#類型系統(tǒng)。C#類型系統(tǒng)一共分為兩類,一類是值類型(Value Type),一類是引用類型(Reference Type)。值類型 和引用類型是以它們?cè)谟?jì)算機(jī)內(nèi)存中是如何被分配的來劃分的。值類型包括 結(jié)構(gòu)和枚舉,引用類型包括類、接口、委托等。還有一種特殊的值類型,稱為簡單類型(Simple Type),比如 byte,int等,這些簡單類型實(shí)際上是FCL類庫類型的別名,比如聲明一個(gè)int類型,實(shí)際上是聲明一個(gè)System.Int32結(jié)構(gòu)類型。因此,在 Int32類型中定義的操作,都可以應(yīng)用在int類型上,比如 “123.Equals(2)”。
所有的 值類型 都隱式地繼承自 System.ValueType類型(注意System.ValueType本身是一個(gè)類類型),System.ValueType和所有的引用類型都繼承自 System.Object基類。你不能顯示地讓結(jié)構(gòu)繼承一個(gè)類,因?yàn)镃#不支持多重繼承,而結(jié)構(gòu)已經(jīng)隱式繼承自ValueType。
1.值類型
當(dāng)聲明一個(gè)值類型的變量(Variable)的時(shí)候,變量本身包含了值類型的全部字段,該變量會(huì)被分配在線程堆棧(Thread Stack)上。假如我們有這樣一個(gè)值類型,它代表了直線上的一點(diǎn):
- public struct ValPoint {
- public int x;
- public ValPoint(int x) {
- this.x = x;
- }
- }
2.引用類型
當(dāng)聲明一個(gè)引用類型變量的時(shí)候,該引用類型的變量會(huì)被分配到堆棧上,這個(gè)變量將用于保存位于堆上的該引用類型的實(shí)例的內(nèi)存地址,變量本身不包含對(duì)象的數(shù)據(jù)。此時(shí),如果僅僅聲明這樣一個(gè)變量,由于在堆上還沒有創(chuàng)建類型的實(shí)例,因此,變量值為null,意思是不指向任何類型實(shí)例(堆上的對(duì)象)。對(duì)于變量的類型聲明,用于限制此變量可以保存的類型。
如果我們有一個(gè)這樣的類,它依然代表直線上的一點(diǎn):
- public class RefPoint {
- public int x;
- public RefPoint(int x) {
- this.x = x;
- }
- public RefPoint() {}
- }
3.關(guān)于簡單類型
很多文章和書籍中在講述這類問題的時(shí)候,總是喜歡用一個(gè)int類型作為值類型 和一個(gè)Object類型作為引用類型來作說明。本文中將采用自定義的一個(gè) 結(jié)構(gòu) 和 類分別作值類型和引用類型的說明。這是因?yàn)楹唵晤愋?比如int)有一些CLR實(shí)現(xiàn)了的行為,這些行為會(huì)讓我們對(duì)一些操作產(chǎn)生誤解。
舉個(gè)例子,如果我們想比較兩個(gè)int類型是否相等,我們會(huì)通常這樣:
- int i = 3;
- int j = 3;
- if(i==j) Console.WriteLine("i equals to j");
實(shí)際上,在后面我們就會(huì)看到,當(dāng)使用“==”對(duì)引用類型變量進(jìn)行比較的時(shí)候,比較的是它們是否指向的堆上同一個(gè)對(duì)象。而上面a、b指向的顯然是不同的對(duì)象,只是對(duì)象包含的值相同,所以可見,對(duì)于string類型,CLR對(duì)它們的比較實(shí)際上比較的是值,而不是引用。
為了避免上面這些引起的混淆,在對(duì)象判等部分將采用自定義的結(jié)構(gòu)和類來分別說明。
裝箱和拆箱
這部分內(nèi)容可深可淺,本文只簡要地作一個(gè)回顧。簡單來說,裝箱 就是 將一個(gè)值類型轉(zhuǎn)換成等值的引用類型。它的過程分為這樣幾步:
1. 在堆上為新生成的對(duì)象(該對(duì)象包含數(shù)據(jù),對(duì)象本身沒有名稱)分配內(nèi)存。
2. 將 堆棧上 值類型變量的值拷貝到 堆上的對(duì)象 中。
3. 將堆上創(chuàng)建的對(duì)象的地址返回給引用類型變量(從程序員角度看,這個(gè)變量的名稱就好像堆上對(duì)象的名稱一樣)。
以上介紹C#類型系統(tǒng)
【編輯推薦】