《Effective C#》讀書筆記——條目13:正確地初始化靜態成員變數

來源:互聯網
上載者:User

  我們知道在C#語言中建立一個類型的執行個體前,就應該初始化該類型的所有靜態成員變數。C#語言為我們提供了靜態初始化器和靜態建構函式。其中,靜態建構函式是一個特殊的建構函式,將在其他所有方法執行前以及變數或屬性被第一次訪問之前將自動調用靜態建構函式,且僅執行一次。我們可以通過使用靜態建構函式來初始化靜態變數、實現單例模式或者執行類在可用之前的所有操作。但是不能夠使用執行個體建構函式專門的私人函數或者其他什麼方式來初始化靜態變數。

  靜態類成員變數也有和執行個體成員類似的初始化器文法,如果只是需要為某個靜態成員分配空間,可以直接使用初始化器文法,但是如果需要使用一些更複雜的邏輯來初始化靜態成員變數那就應該直接使用靜態建構函式。

 

1.單例模式中的靜態建構函式

  在C#中實現單例模式是靜態建構函式的一個常見情境。只需要將執行個體建構函式聲明為私人,然後添加一個初始化器即可:

 1     public class Singleton 2     { 3         /// <summary> 4         /// 靜態成員變數,添加 readonly 關鍵字 5         /// </summary> 6         private static readonly Singleton theOneAndOnly = new Singleton(); 7  8         /// <summary> 9         /// 唯讀靜態屬性10         /// </summary>11         public static Singleton TheOnly12         {13             get { return theOneAndOnly; }14         }15 16         /// <summary>17         /// 私人的執行個體建構函式18         /// </summary>19         private Singleton()20         {21         }22     }

編譯器產生的程式碼類似於下面:

 1     public class Singleton 2     { 3         /// <summary> 4         /// 靜態成員變數,添加 readonly 關鍵字 5         /// </summary> 6         private static readonly Singleton theOneAndOnly; 7  8         /// <summary> 9         /// 唯讀靜態屬性10         /// </summary>11         public static Singleton TheOnly12         {13             get { return theOneAndOnly; }14         }15 16         /// <summary>17         /// 靜態建構函式18         /// </summary>19         static Singleton()20         {21             theOneAndOnly = new Singleton();22         }23 24         /// <summary>25         /// 私人的執行個體建構函式26         /// </summary>27         private Singleton()28         {29         }30     }

和執行個體初始化器類似,靜態初始化器在任何靜態建構函式之前執行。而且,靜態初始化器在調用基類的靜態建構函式之前執行。

 

2.關於靜態建構函式

   靜態建構函式用於初始化任何待用資料,在建立第一個執行個體或者引用任何靜態成員之前,靜態建構函式將會被CLR調用來初始化類,且僅調用一次。

靜態建構函式具有如下特點: 

  • 靜態建構函式既沒有存取修飾詞也不接受任何參數
  • 在建立第一個執行個體或者引用任何靜態成員之前,靜態建構函式將會被CLR調用來初始化類
  • 不能直接調用靜態建構函式,並且在程式中不受控制
  • 如果靜態建構函式引發異常,CLR將不會嘗試再次調用該建構函式,在Application 領域(AppDomain)內,類型將保持未初始化,這會導致該類及其衍生類別建立的類型沒有得到完全初始化

 

3.靜態初始化器&靜態建構函式

   通過前面關於靜態建構函式的特點,我們知道:如果靜態建構函式引發異常,在該次Application 領域(AppDomain)內CLR將不會嘗試再次調用該建構函式,這會導致該類及其衍生類別建立的類型沒有得到完全初始化。

  如果直接只用靜態初始化器文法:編譯器會添直接將靜態成員初始化代碼加入到靜態建構函式中,並且沒有任何異常處理。所以在使用靜態初始化器時,我們無法捕獲並處理異常。然而在我們可以直接在靜態建構函式中添加try/catch代碼塊了進行異常處理。如下:

 1     public class Singleton 2     { 3         /// <summary> 4         /// 靜態成員變數,添加 readonly 關鍵字 5         /// </summary> 6         private static readonly Singleton theOneAndOnly; 7  8         /// <summary> 9         /// 唯讀靜態屬性10         /// </summary>11         public static Singleton TheOnly12         {13             get { return theOneAndOnly; }14         }15 16         /// <summary>17         /// 直接在靜態建構函式中進行異常處理18         /// </summary>19         static Singleton()20         {21             try22             {23                 theOneAndOnly = new Singleton();24             }25             catch26             {27                 //......28             }29         }30 31         /// <summary>32         /// 私人的執行個體建構函式33         /// </summary>34         private Singleton()35         {36         }37     }

 

 

小節:

  靜態初始化器和靜態建構函式是初始化靜態成員的最佳選擇,容易理解並且不易出錯。在其他語言中,這兩個特性也是專門用來方便初始化靜態成員而提供的。如果你需要在你的代碼初始化靜態成員的代碼中進行異常處理是可以直接使用靜態建構函式,在建構函式中添加異常處理代碼;如果是只需要對靜態成員進行空間的分配那麼直接使用初始化器文法即可——在聲明靜態成員的時候對其進行初始化。

 

進一步閱讀&參考資料

MSDN:靜態建構函式

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.