C#箴言:用靜態建構函式初始化靜態成員

來源:互聯網
上載者:User
編寫程式的時候難免要使用到靜態成員,由於靜態成員的訪問是脫離類型對象的,所以使用非靜態建構函式,私人方法或者一些其他方法都是不合理的。.Net提供了成員初始化語句和靜態建構函式來初始化靜態成員。

  根據上一個單元,我們可以知道靜態成員的初始化語句會早於靜態建構函式執行,其次還知道成員初始化語句的好處和一些限制。這裡要提的一點就是,靜態建構函式和執行個體建構函式之間的區別,因為靜態建構函式是由CLR調用執行的,所以靜態建構函式只能是一個,同時不能還有參數。那麼靜態建構函式相對於成員初始化的一些弊端都不複存在。

  此外,對於成員初始化最大的問題,就是異常無法捕獲,可能對於普通成員來說,還可以在構造類型對象的時候加上try-catch;而對於靜態成員來說,有時無法確定哪一個類型訪問語句會先執行,如果對每個使用類型的地方都加上try-catch,會降低程式可讀性。但如果把這種異常散發出去,會導致整個程式崩潰。那麼使用靜態建構函式就能比較好的捕獲異常,並進行異常處理。

  對於靜態成員初始化語句和靜態建構函式一個對比大致如下。

  簡便性 安全性 異常處理
靜態成員初始化 最簡便 比較安全 非常難
靜態建構函式 比較簡便 最安全 容易

  那麼到底用什麼方法來初始化靜態成員呢,給出以下兩點建議:

  第一就是簡單靜態成員,例如類型為實值型別等,使用成員初始化語句來完成;

  第二靜態成員初始化比較複雜,或者有可能出現異常,那麼用靜態建構函式來完成。

  本單元的內容基本上講完了,現在說說靜態成員最主要的一個應用“Singleton”,就是保證此類型的對象唯一性。其實實現很簡單,如下就舉一個簡單的例子。

public class MySingleton
{
 private static readonly MySingleton _theOneAndOnly;
 static MySingleton()
 {
  _theOneAndOnly = new MySingleton();
 }
 public static MySingleton TheOnly
 {
  get{ return _theOneAndOnly; }
 }

 /// <summary>
 /// Private constructor to avoid object created from outside
 /// </summary>

 private MySingleton()
 {}
}

  對於靜態成員何時被初始化,其實仔細看我上一個單元所說的物件建構步驟就可以分析出來。可能看起來比較抽象,尤其在分析嵌套關係的時候,現在就舉一個例子來進行說明。

class A
{
 public static int X = B.Y;
 static A()
 {
  ++X;
 }
}

class B
{
 public static int Y = A.X;
 static B()
 {
  ++Y;
 }
}

  那麼大家先猜猜如下調用輸出結果是什麼。

Debug.WriteLine( A.X.ToString() );
Debug.WriteLine( B.Y.ToString() );

  其結果是“2,1”,也就是A.X的值為2,而B.Y的值為1。

  分析此類問題,只要記住三點就行了。
  
  第一代碼的執行順序,代碼在前的先執行;

  第二靜態成員初始化語句要先於靜態建構函式執行;

  第三靜態成員初始化語句與靜態建構函式只執行一次。

  如果瞭解這三點,接下來就分析為什麼會出現上面的結果。

  當調用到第一條語句的時候,

Debug.WriteLine( A.X.ToString() );

  首先是訪問A這個類型,那麼要對A這個類型的靜態成員進行初始化,其次如果有靜態建構函式,需要調用它。

  對於A的靜態成員只有“X”,按照上一單元的過程,先給其分配空間,並輔以0來初始化,其次調用其對應的成員初始化語句來初始化這個靜態成員。

  那麼它的成員初始化語句是“X = B.Y”,那麼需要訪問“B.Y”來初始化X這個靜態成員。

  對於“B.Y”的訪問,就是訪問B類型,也是和訪問A一樣,首先對這個類型的靜態成員進行初始化,其次如果有靜態建構函式,需要調用它。而B的靜態成員只有“Y”,先給其分配空間,並輔以0來初始化,其次調用其對應的成員初始化語句來初始化這個靜態成員。

  那麼對於“Y = A.X”成員初始化語句,由於此時不是第一次訪問類型A,所以不再進行靜態成員初始化和靜態建構函式的調用,對於“A.X”的訪問是直接存取。此時“A.X”的值為0,那麼Y的值也為0;接著執行B的靜態建構函式,這樣處理後Y的值為1。

  那麼對於A中的成員初始化語句“X = B.Y”,到此就執行完了,此時A類型中的X與B類型中的Y都是一樣的,值為1。不過B中的靜態成員初始化語句和靜態建構函式都執行過了,而A中的靜態建構函式還未執行。因此經過A的靜態建構函式處理,A的X值為2,這也就是最後顯示的結果。

  分析過程看起來很繞,其實只要把握我前面所說的三個原則,那麼在複雜的問題也一樣分析。

-----------------------------------------------

原文連結地址:http://soft.yesky.com/188/2561688.shtml

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.