標籤:oid copy class 情境 png 靜態成員變數 建構函式 alt 一個
建構函式這個概念,在我們剛開始學習程式設計語言的時候,就被老師一遍一遍的教著。親,現在你還記得靜態建構函式的適用情境嗎?如果沒有,那麼我們一起來複習一下吧。
靜態建構函式是在建構函式方法前面添加了static關鍵字之後形成的,並且沒有修飾符(public,private),沒有參數。
靜態建構函式有哪些特點呢:
- 靜態建構函式沒有修飾符修飾(public,private),因為靜態建構函式不是我們程式員調用的,是由.net 架構在合適的時機調用的。
- 靜態建構函式沒有參數,因為架構不可能知道我們需要在函數中添加什麼參數,所以規定不能使用參數。
- 靜態建構函式前面必須是static 關鍵字。如果不加這個關鍵字,那就是普通的建構函式了。
- 靜態建構函式中不能執行個體化執行個體變數。(變數可以分為類層級和執行個體層級的變數,其中類層級的有static關鍵字修飾)。
- 靜態函數的調用時機,是在類被執行個體化或者靜態成員被調用的時候進行調用,並且是由.net架構來調用靜態建構函式來初始化靜態成員變數。
- 一個類中只能有一個靜態建構函式。
- 無參數的靜態建構函式和無參數的建構函式是可以並存的。因為他們一個屬於類層級,一個屬於執行個體層級,並不衝突。
- 靜態建構函式只會被執行一次。並且是在特點5中的調用時機中進行調用。
- 就像如果沒有在類中寫建構函式,那麼架構會為我們產生一個建構函式,那麼如果我們在類中定義了靜態變數,但是又沒有定義靜態建構函式,那麼架構也會協助我們來產生一個靜態建構函式來讓架構自身來調用。
上面幾個特點都是理論性的,我們來做一個找錯題,協助我們一起來學習靜態建構函式。
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 A12 {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:A25 {26 static B()27 {28 strText = "BBB";29 }30 public B()31 {32 Text = "BBBBBBBBBBBBBBBBB";33 }34 }
輸出結果均為:AAA
我們來分析一下出現這個情況的原因所在,當顯示A.strText的時候,因為strText是靜態變數,所以架構會調用A的靜態建構函式,此時strText的值為AAA.正確
當顯示B.strText的時候,因為B繼承自A,所以會首先調用A的靜態建構函式,但是因為靜態建構函式只會調用一次,所以不會調用A的靜態建構函式,但是又因為strText屬於類A,而不是B,所以B得靜態建構函式不會執行,故輸出的均為AAA。
但是如果我們把輸出更改一下,輸出結果就大不一樣了。
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 A15 {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:A28 {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。
c#靜態建構函式 與 建構函式 你是否還記得?