c#靜態構造函數 與 構造函數 你是否還記得?

    構造函數這個概念,在咱們剛開始學習編程語言的時候,就被老師一遍一遍的教着。親,如今你還記得靜態構造函數的適用場景嗎?若是沒有,那麼咱們一塊兒來複習一下吧。程序員

靜態構造函數是在構造函數方法前面添加了static關鍵字以後造成的,而且沒有修飾符(public,private),沒有參數。編程

靜態構造函數有哪些特色呢:框架

  1. 靜態構造函數沒有修飾符修飾(public,private),由於靜態構造函數不是咱們程序員調用的,是由.net 框架在合適的時機調用的。
  2. 靜態構造函數沒有參數,由於框架不可能知道咱們須要在函數中添加什麼參數,因此規定不能使用參數。
  3. 靜態構造函數前面必須是static 關鍵字。若是不加這個關鍵字,那就是普通的構造函數了。
  4. 靜態構造函數中不能實例化實例變量。(變量能夠分爲類級別和實例級別的變量,其中類級別的有static關鍵字修飾)。
  5. 靜態函數的調用時機,是在類被實例化或者靜態成員被調用的時候進行調用,而且是由.net框架來調用靜態構造函數來初始化靜態成員變量。
  6. 一個類中只能有一個靜態構造函數。
  7. 無參數的靜態構造函數和無參數的構造函數是能夠並存的。由於他們一個屬於類級別,一個屬於實例級別,並不衝突。
  8. 靜態構造函數只會被執行一次。而且是在特色5中的調用時機中進行調用。
  9. 就像若是沒有在類中寫構造函數,那麼框架會爲咱們生成一個構造函數,那麼若是咱們在類中定義了靜態變量,可是又沒有定義靜態構造函數,那麼框架也會幫助咱們來生成一個靜態構造函數來讓框架自身來調用。

上面幾個特色都是理論性的,咱們來作一個找錯題,幫助咱們一塊兒來學習靜態構造函數。編程語言

 1     public class C
 2     {
 3         public static string BB;
 4         public static C()
 5         {
 6             BB = "CC";
 7         }
 8         public static C(string mm)
 9         {
10             BB = mm;
11         }
12         static C()
13         {
14             BB = "Right";
15         }
16         public C()
17         {
18             BB = "Wrong";
19         }
20         public C(string mm)
21         {
22             BB = mm;
23         }
24     }

VS編譯提示的錯誤信息:函數

 

如今咱們來作一個有意思的事情,驗證靜態構造函數的調用時機:學習

 1  class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5 
 6             Console.WriteLine(A.strText);
 7             Console.WriteLine(B.strText);
 8             Console.Read();
 9         }
10     }
11     public class A
12     {
13         public static string strText;
14         public string Text;
15         static A()
16         {
17             strText = "AAA";
18         }
19         public A()
20         {
21             Text = "AAAAAAAAAAAAAAAAAAAAAAAAAA";
22         }
23     }
24     public class B:A
25     {
26         static B()
27         {
28             strText = "BBB";
29         }
30         public B()
31         {
32             Text = "BBBBBBBBBBBBBBBBB";
33         }
34     }

輸出結果均爲:AAAspa

咱們來分析一下出現這個狀況的緣由所在,當顯示A.strText的時候,由於strText是靜態變量,因此框架會調用A的靜態構造函數,此時strText的值爲AAA.正確.net

當顯示B.strText的時候,由於B繼承自A,因此會首先調用A的靜態構造函數,可是由於靜態構造函數只會調用一次,因此不會調用A的靜態構造函數,可是又由於strText屬於類A,而不是B,因此B得靜態構造函數不會執行,故輸出的均爲AAA。code

 

可是若是咱們把輸出更改一下,輸出結果就大不同了。blog

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             B b = new B();
 6             A a = new A();
 7 
 8             Console.WriteLine(A.strText);
 9             Console.WriteLine(B.strText);
10           
11             Console.Read();
12         }
13     }
14     public class A
15     {
16         public static string strText;
17         public string Text;
18         static A()
19         {
20             strText = "AAA";
21         }
22         public A()
23         {
24             Text = "AAAAAAAAAAAAAAAAAAAAAAAAAA";
25         }
26     }
27     public class B:A
28     {
29         static B()
30         {
31             strText = "BBB";
32         }
33         public B()
34         {
35             Text = "BBBBBBBBBBBBBBBBB";
36         }
37     }

請注意我在開始部分對類進行了實例化,那麼此時的輸出結果就是均爲BBB。

爲何會有這樣的狀況出現呢,其實仍是要從靜態構造函數的調用時機入手。

首先咱們實例化了B,此時會調用B的靜態構造函數,可是由於strText是A的靜態變量,因此首先會先調用A的靜態構造函數將strText賦值爲AAA,此時又會調用B的靜態構造函數將strText賦值爲BBB,因此此時strText的值應該爲BBB,因此輸出均爲BBB。

相關文章
相關標籤/搜索