C# 實例化類的執行順序


先進行細分:

類的成員分為:字段、屬性、方法、構造方法

成員的修飾符:靜態成員、實例成員

層次結構:父類、子類


 先不考慮繼承關系,執行順序為:

  1. 靜態字段
  2. 靜態構造方法
  3. 實例字段
  4. 實例構造方法

屬性和方法是在調用的時候才執行,這里就不考慮了。如何理解上面的執行過程?假如讓我來設計執行過程,我該如何考慮,依據是什么?

首先,靜態的東西是大家共享的,也就是相同的。應該先關心共享的東西,再關系個人的東西。“先公后私”,呵呵。

其次,實例化之前,應該先初始化自己的內部數據。


 現在考慮繼承關系,執行順序為:

  1. 子類的靜態字段
  2. 子類的靜態構造方法
  3. 子類的實例字段
  4. 父類的靜態字段
  5. 父類的靜態構造方法
  6. 父類的實例字段
  7. 父類的實例構造方法
  8. 子類的實例構造方法

在子類的實例字段和子類的實例構造方法之間,加入了父類的執行順序。這個其實也很好理解:在子類的實例構造方法之前,確實需要知道父類的信息,因為子類要從父類那里繼承一些東西。這就好比,沒有老子,哪來的兒子呢,呵呵。


這里需要特別注意的是,並不是每次實例化都是上面的順序。因為靜態的成員只是在第一次實例化的時候執行,以后再實例化都不會在執行。很好理解,靜態的成員意味着大家共享,且只有這一個。第一次實例化得到靜態成員后,以后大家都共享,再次實例化,沒有必要也不允許執行靜態成員的部分。


 補充說明:

1、構造引用類型的對象時,調用實例構造方法之前,為對象分配的內存總是先被歸零,構造器沒有顯式重寫字段,字段的值為0或者null

2、原則上講,類中的字段應該在實例構造方法內初始化。C#編譯器提供了簡化的語法,允許在變量定義的時候初始化。但在幕后,C#會把這部分代碼搬到構造方法內部。因此,這里存在代碼膨脹的問題。多個字段在定義時初始化,同時存在多個構造方法,每個構造方法都會把這些字段初始化的代碼搬到自己的內部,這樣造成代碼的膨脹。為了避免這樣情況,可以把這些字段的初始化放到一個無參構造方法內,其他的構造方法顯式調用無參構造方法。

3、初始化類的字段有兩種方法,①使用簡化語法,在定義的時候初始化;② 在構造方法內初始化。使用簡化語法初始化的代碼,會被搬到構造方法內。特別注意,在生成的IL中,父類構造方法會夾在 ①和②之間。因此,實例化子類的時候,會先執行①,再執行父類構造方法,然后執行②。現在問題來了,假如在父類構造方法內,調用虛方法,虛方法回調子類的方法,子類方法使用字段,這時候字段的值是簡化語法初始化的值。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM