第四章 型別基礎

2022-07-16 09:09:08 字數 2972 閱讀 7445

4.1 所有型別都從system.object派生

"執行時"要求每個型別最終都從system.object型別派生。

system.object 公共例項方法:

equals:如果兩個物件具有相同的值,就返回true。

gethashcode:返回物件的值得雜湊碼。如果某個型別的物件要在雜湊表集合中作為建使用,型別應該重寫改方法。方法應該為不同物件提供良好分布。

tostring:預設返回型別的完整名稱(this.gettype().fullname)。但經常重寫改方法來返回包含物件狀態表示的string物件。

gettype:返回從type派生的乙個型別的例項,指出呼叫gettype的那個物件時什麼型別。返回的type物件可以和反射類配合,獲取與物件的型別有關的元資料資訊。gettype是非虛方法,目的是防止類重寫該方法。隱藏其型別,進而破壞型別的安全性。

受保護方法:

memberwiseclone:這個非虛方法建立型別的新例項,並將新物件的例項欄位設與this物件的例項字段完全一致。返回對新例項的引用。

finalize:在垃圾**器判讀物件應該作為垃圾被**之後,在物件的記憶體被實際**之前,會呼叫這個虛方法。需要在**記憶體前執行清理工作的型別應該重寫該方法。

new操作符:clr要求所有物件都用new操作符建立。

1.計算型別及其所有基型別(一直到system.object)中定義的所有例項字段需要的位元組數。堆上每個物件都需要一些額外的成員(overhead成員:開銷成員),型別物件指標和同步塊索引。clr利用這些成員管理物件。額外成員的位元組數要計入物件大小。

2.從託管堆中分配型別要求的位元組數,從而分配物件的記憶體。分配的所有位元組都設為零(0)。

3.初始化物件的「型別物件指標」和「同步塊索引」。

4.呼叫型別的例項構造器,傳遞在new呼叫中指定的實參。大多數編譯器都在 構造器中自動生成**來呼叫基類構造器。每個型別的構造器都負責初始化型別定義的例項字段。最終呼叫system.object的構造器,該構造器沒有例項字段,什麼都不做,簡單地返回。

new執行了所有這些操作後,返回指向新建物件的乙個引用(或指標)。

clr最重要的特性之一就是型別安全。

clr允許將物件轉換為它的實際型別或者它的任何基型別。

is和as操作苻

is檢查物件是否相容於指定型別,返回boolcan值true或false。is操作符永遠不丟擲異常。如果物件引用為null,is操作符總是返回false。

as操作符的工作方式與強制型別轉換一樣,只是它永遠不丟擲異常,如果物件不能轉型,結果就是null。

命名空間對相關的型別進行邏輯分組,開發人員可通過命名空間方便地定位型別。

using指令:減少打字量,允許為型別或命名空間建立別名。

程序可能有多個執行緒,執行緒建立時會分配到1mb的棧。棧空間用於向方法傳遞實參,方法內部定義的區域性變數也在棧上。棧從高位記憶體到低位記憶體位址構建。

最簡單的方法包含「序幕」**,在方法開始做工作前對其進行初始化;還包含「尾聲」**,在方法做完工作後對其進行清理,以便返回至呼叫者。

呼叫方法時,會把作為實參的區域性變數中的位址壓入棧,用被呼叫的方法的形參變數標誌棧位置。 還會將「返回位址」壓入棧。被呼叫的方法在結束之後返回至該位置。

jit編譯器將方法中的il**轉換成本機cpu指令時,會注意到方法內部引用的所有型別。這時clr要確認定義了這些型別的所有程式集都已載入。然後利用程式集的元資料,clr提取與這些型別相關的資訊,建立一些資料結構(在堆中)來表示型別本身。(型別物件使用的資料結構)

定義型別時,可在型別內部定義靜態資料字段。為這些靜態資料字段提供支援的位元組在型別物件自身中分配。每個型別物件最後都包含乙個方法表(methoddef方法表),方法表中型別定義的每個方法都有對應的記錄項。

當clr確認方法需要的所有型別物件都已建立後,方法的**已經編譯之後,就允許執行緒執行方法的本機**。

呼叫靜態方法時:clr會定位與定義靜態方法的型別對應的型別物件。然後jit編譯器在型別物件的方法表中查詢與被呼叫方法對應的記錄項,對方法進行jit編譯,在呼叫編譯好的**。在內部,靜態方法在堆上構造乙個新的物件,和返回物件位址並儲存到變數中。

呼叫非虛例項方法時:編譯器會找到與「發出呼叫的那個變數的型別」對應的型別物件。如果型別沒有定義正在呼叫的那個方法,jit會回溯類層次結構(一直回溯到system.object),並在沿途的每個型別中查詢該方法。然後jit在型別的物件的方法表中查詢引用了被呼叫方法的記錄項,對方法進行jit編譯(如果需要的話),再呼叫jit編譯好的**。

呼叫需例項方法時:jit編譯器要在方法中生成一些額外的**;方法每次呼叫都會執行這些**。這些**首先檢查發出呼叫的變數,並跟隨位址來到發出呼叫的變數。然後,**檢查物件內部的「型別物件指標」成員,該成員指向物件的實際型別。然後**在型別物件的方法表中查詢引用了被呼叫方法的記錄項,對方法進行編譯,再呼叫。

型別物件本質上也是物件。clr建立型別物件時,必須初始化這些成員。clr開始在乙個程序中執行時,會立即為mscorlib.dll中定義的system.type型別建立乙個特殊的型別物件。所有型別物件都是該型別的「例項」。物件中的型別物件指標成員會初始化成對system.type型別物件的引用。

system.type型別物件本身也是物件,內部「型別物件指標」指向它本身,因為system.type型別物件本身也是乙個型別物件的「例項」。system.object的gettype方法返回儲存在指定物件的「型別物件指標」成員中的位址。也就是說,gettype方法返回指向物件的型別物件指標。這樣就可以判斷系統中任何物件的真實型別。

第四章 型別基礎

這章不好理解,我是連抄帶找的。一 system.object 所有型別的基類,也就是所有型別從它派生。公開了幾個方法 equals 判定兩個物件是否具有相同的值 相等性和同一性後續討論 gethashcode tostring 預設返回型別的完整名稱,但是經常會重寫返回表示物件狀態的 string ...

《CLR via C 》第四章《型別基礎》

在coding中,任何型別都是繼承於system.object的,形如public class physicalgc basecommand其實完整的寫法應該是public class physicalgc basecommand system.object既然繼承了system.object,那就...

第四章 復合型別

第一題 按示例請求顯示資訊。第二題 修改程式4.4,使用c string類 include include using namespace std int main 第三題 使用char陣列,和cstring中的函式,按示例格式顯示輸出 include include using namespace...