《CLR via C 》讀書筆記 之 方法

2021-09-06 08:20:58 字數 1461 閱讀 9433

2013-02-27

8.1 例項構造器和類(引用型別)

8.2 例項構造器和結構(值型別)

8.3 型別構造器

8.6 擴充套件方法返回

建立引用型別的例項的過程

(1)       為例項的資料字段分配記憶體(例項字段包括本身及其基類的例項字段)

(2)       然後初始化物件的附加字段(型別物件指標和同步塊索引)

(3)       呼叫型別的例項構造器來設定物件的初始狀態。

基類的構造器總是在類的例項構造器之前呼叫,這是為了使**「可驗證」(當類的例項構造器訪問從基類繼承來的字段)。因此,不要再構造器中呼叫虛方法(比如這個虛方法要在子類中重寫,可是重寫方法所用欄位還沒初始化)。

c#提供簡單語法,允許在構造引用型別例項時,對型別中定義的字段進行「內聯」初始化

1

class

sometype

2

我們通過sometype構造器的il**發現,字段初始化的**會在幕後移入到構造器中,構造器il**的執行順序為:字段初始化=》基類構造器=》構造器本身的**,因此,盡量把初始化任務放在構造器中。

和其他方法不同,例項構造器永遠不能被繼承。

c#編譯器將定義乙個預設(無參)構造器,下表顯示類修飾符與預設構造器的關係。

表1類修飾符與預設構造器的關係

類的修飾符

預設構造器

無abstract

預設構造器可訪問性為public

有abstract

預設構造器可訪問性為protected

static(靜態類在元資料中是抽象密封類)

編譯器根本不會在類中定義生成乙個預設構造器返回

值型別(struct)構造器的工作方式與引用型別(class)的構造器截然不同。c#編譯器根本不會為值型別生成無參構造器。即使為值型別提供了無參構造器,許多編譯器也永遠不會生成**呼叫它。c#編譯器乾脆不允許值型別定義無參構造器,也不允許值型別中內聯方式初始化例項字段。

注意:嚴格的說,只有當值型別的字段巢狀到引用型別中時,才保證會被初始化為0或null。但是,基於棧的值型別欄位不保證為0或null。

為了**的「可驗證性」(verifiablity),任何基於棧型別的子型別都必須在讀取前寫入(賦值)。如果允許**先讀再寫,就會造成安全漏洞,所以c#和其他生成「可驗證」**的編譯器可以保證對它們進行「置零」。返回

型別預設沒有定義型別構造器,如果定義,也只能定義乙個。此外,型別構造器永遠沒有引數。

型別構造器必須標記為static,而且,總是私有的,c#會自動把它們標記為private。

型別構造器不應呼叫其基型別的型別構造器。這種呼叫沒有必要,因為型別並沒有從其基型別繼承靜態字段。返回

對無法修改的類擴充其方法,要小心使用。

《CLR via C 》讀書筆記 之 引數

2013 02 27 預設情況下,clr假定所有方法引數都是傳值的。當傳遞引用型別的物件時,也預設是傳值的,只不過這個值是引用 指標 本身。clr允許以傳引用的方式傳遞引數。在c 中,用關鍵字out或ref來告訴編譯器。編譯器將傳遞引數的位址,而不是傳遞引數本身。從clr角度看,out和ref完全一...

CLR via C 讀書筆記1 9

與非託管 的互操作 clr 提供3種與非託管 的互動方案 託管 通過使用 p invoke 機制 來呼叫dll檔案中的非託管函式 許多 fcl 中定義的型別內部都有呼叫到 kernel32.dll,user32.dll 等等檔案中的函式。同時許多程式語言會提供託管 呼叫非託管 的簡便途徑,比如 c ...

CLR via C 讀書筆記2 2

把型別編譯成乙個模組 先假設有這麼乙個簡單的程式 public sealed class program 該程式定義乙個名為 program 的型別,它擁有乙個公有靜態 public,static 方法 main,該方法參照 system.console。把源 存為 program.cs 執行以下命...