C# 之 靜態字段初始化


      當一個字段聲明中含有 static 修飾符時,由該聲明引入的字段為靜態字段(靜態變量)。當不存在 static 修飾符時,由該聲明引入的字段為實例字段(實例變量)。
      靜態字段不屬於某個特定的實例;相反,它只標識了一個存儲位置。不管創建了多少個類實例,對於關聯的應用程序域來說,在任何時候靜態字段都只會有一個副本。實例字段屬於某個實例。具體說來,類的每個實例都包含了該類的所有實例字段的一個單獨的集合。
(2)字段聲明可以包含變量初始值設定項,兩者初始化區別如下:
  對於靜態字段,變量初始值設定項相當於在類初始化期間執行的賦值語句。
  對於實例字段,變量初始值設定項相當於創建類的實例時執行的賦值語句。
示例如下:
using System;
class Test
{
   static double x = Math.Sqrt(2.0);
   int i = 100;
   string s = "Hello";
   static void Main() {
      Test a = new Test();
      Console.WriteLine("x = {0}, i = {1}, s = {2}", x, a.i, a.s);
   }
}

產生輸出:

x = 1.4142135623731, i = 100, s = Hello

這是因為對 x 的賦值發生在靜態字段初始值設定項執行時,而對 is 的賦值發生在實例字段初始值設定項執行時。

(3)類的靜態字段變量初始值設定項對應於一個賦值序列,這些賦值按照它們在相關的類聲明中出現的文本順序執行。如果類中存在靜態構造函數,則靜態字段初始值設定項的執行在該靜態構造函數即將執行前發生。否則,靜態字段初始值設定項在第一次使用該類的靜態字段之前先被執行,但實際執行時間依賴於具體的實現。

如下示例:

using System;
class Test
{
   static void Main() {
      Console.WriteLine("{0} {1}", B.Y, A.X);
   }
   public static int F(string s) {
      Console.WriteLine(s);
      return 1;
   }
}
class A
{
   public static int X = Test.F("Init A");
}
class B
{
   public static int Y = Test.F("Init B");
}

或產生輸出

Init B
Init A
1 1

這是因為 X 的初始值設定項和 Y 的初始值設定項的執行順序無法預先確定,上述兩種順序都有可能發生;唯一能夠確定的是:它們一定會在對那些字段的引用之前發生。但是,下面的示例:

using System;
class Test
{
   static void Main() {
      Console.WriteLine("{0} {1}", B.Y, A.X);
   }
   public static int F(string s) {
      Console.WriteLine(s);
      return 1;
   }
}
class A
{
   static A() {}
   public static int X = Test.F("Init A");
}
class B
{
   static B() {}
   public static int Y = Test.F("Init B");
}

所產生的輸出必然是:

Init B
Init A
1 1

這是因為關於何時執行靜態構造函數的規則(在第 10.11 節中定義)規定:B 的靜態構造函數(以及 B 的靜態字段初始值設定項)必須在 A 的靜態構造函數和字段初始值設定項之前運行。

 

 

 

 


免責聲明!

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



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