建構函式不可繼承、不可用 virtual/new/override/sealed/abstract。無顯式建構函式時編譯器產生預設無參建構函式(僅呼叫基底類別無參建構函式)。抽象類別預設建構函式為 protected,否則為 public;static 類別不產生預設建構函式。基底類別無無參建構函式時,衍生類別必須顯式 : base(...) 呼叫。最終皆呼叫 System.Object 公用無參建構函式。反序列化與 MemberwiseClone 不需實例建構函式。內聯欄位初始化實際發生在預設建構函式中。
new 時才執行建構函式語句。cctor 無意義——無機會執行。cctor 互相引用(順序不確定)。cctor 拋出異常 → 型別不可用,後續操作拋 TypeInitializationException。cctor 僅存取靜態欄位,用途即初始化靜態欄位;內聯初始化效果相同。不應呼叫基底類別 cctor(無關係)。CLR 不支援靜態 Finalize。效能:Precise(cctor 初始化)vs BeforeFieldInit(內聯初始化)。差異在於 IL 是否附加 BeforeFieldInit 標記。文中附基準測試程式碼(Stopwatch)。
CLR 不認識運算子;運算子為 C# 定義,對應編譯器識別方法。運算子重載為 public static,分一元/二元。要求至少一個參數與重載方法類型相同。參數不可用 ref/out。例:+ 對應 op_Addition(屬於 specialname 群組)。建議同時定義友好方法(如 Add)。
System.Decimal 為絕佳學習範例。implicit/explicit 運算子為 public static,封裝建構函式與 ToXXX 方法。IL 中同名方法僅回傳類型不同(僅 IL 允許)。
ref:呼叫前必須初始化;方法內可修改。out:呼叫前可未初始化;方法內必須賦值。ref/out 等效;C# 有區別。方法可基於 ref/out 多載,但不可僅因 ref/out 差異多載。Swap<T>(ref T, ref T) 為標準交換寫法。ProcessFiles(ref FileStream fs) 實現流水線處理。僅最後一個參數可為 params,必須為一維陣列。可傳 null、零長度陣列、甚至省略(預設零長度陣列)。呼叫時無需建立陣列物件。
IEnumerable<T> 而非 IList<T>)。FileStream 而非 Stream)。IList<T> 而非 List<T>)。