靜態變數
靜態變數位於棧上,它是一個全域變數,在編譯期就已經產生。
public class Cow{public static int count;private int id;public Cow(){id = ++count;}}
用戶端建立2個Cow的執行個體,並列印靜態變數count。
static void Main(string[] args){Console.WriteLine(Cow.count);Cow cow1 = new Cow();Cow cow2 = new Cow();Console.WriteLine(Cow.count);}
結果:
0
2
○ 在建立Cow執行個體之前,全域就已經有了count這個靜態變數
○ 如果在static之前用private修飾,就不可以通過"類名.靜態欄位名"來訪問靜態欄位,但全域的靜態欄位始終存在
在堆和棧上的表現,如下圖:
靜態建構函式
在Cow類中添加一個靜態建構函式。
public class Cow{public static int count;private int id;public Cow(){id = ++count;}static Cow(){count = new Random().Next(100);}}
在建構函式和靜態建構函式中,都對Cow的靜態欄位賦值。現在我們想瞭解靜態建構函式在什麼時候觸發。是在用建構函式建立執行個體的時候觸發嗎?會不會在設定Cow的欄位或屬性值的時候觸發?在用戶端,通過列印靜態欄位count的值來瞭解靜態建構函式什麼時候被觸發。
static void Main(string[] args) { Cow cow1 = new Cow(); Console.WriteLine("建立第一個Cow執行個體後count為:"+ Cow.count); Cow cow2 = new Cow(); Console.WriteLine("建立第二個Cow執行個體後count為:" + Cow.count); }
○ 靜態建構函式在建立第一個Cow執行個體的時候被觸發
○ 在建立第二個Cow執行個體的時候,靜態建構函式沒有被觸發,而是通過建構函式建立執行個體
○ 靜態建構函式只執行一次
由此,我們是否可以這樣定論:靜態建構函式是在建立第一個執行個體時候被觸發的?
橫看成嶺側成峰,來換個角度思考這個問題。在為類的欄位賦值時,會不會觸發靜態建構函式呢?
把Cow類修改為:
public class Cow{public static int count;private int id;public static int whatever;public Cow(){id = ++count;}static Cow(){count = new Random().Next(100);whatever = count + 10;Console.WriteLine("靜態建構函式被觸發後count為:" + Cow.count);Console.WriteLine("靜態建構函式被觸發後whatever為:" + Cow.whatever);}}
用戶端修改為:
static void Main(string[] args){Cow.count = 100;Cow cow1 = new Cow();Console.WriteLine("建立第一個Cow執行個體後count為:"+ Cow.count);Cow cow2 = new Cow();Console.WriteLine("建立第二個Cow執行個體後count為:" + Cow.count); }
○ 在為Cow的欄位賦值之前,靜態建構函式被觸發
○ 接著建立Cow執行個體,靜態建構函式不會被再次觸發
○ 靜態建構函式只執行一次
到這裡,關於靜態建構函式被觸發的時機,我們可以這樣下結論:無論是通過建構函式建立執行個體,還是給類的欄位或屬性賦值,靜態建構函式是在所有這些動作之前被觸發的。
靜態類
首先建立一個類,包括靜態成員和非靜態成員。
public class Logger{ private static int logNumber = 0;static public void InitializeLogging(){Console.WriteLine("日誌初始化");}static public void CloseLog(){Console.WriteLine("日誌關閉");}static public void LogMsg(string msg){Console.WriteLine("日誌編號為:" + logNumber + ":" + msg);}public void DoSth(){Console.WriteLine("我不是靜態方法~~");}}
在用戶端,既可以通過"類名.靜態方法名稱"調用方法,也可以通過類的執行個體調用方法。
static void Main(string[] args){Logger.InitializeLogging();Logger.LogMsg("日誌被記錄下了~~");Logger.CloseLog();Logger logger = new Logger();logger.DoSth();}
如果把一個類設定成靜態類,意味著:這個類的所有一切存在於棧上,因此該類中不能有執行個體方法,也不能建立該類執行個體。
修改Logger類,把執行個體方法去掉。
public static class Logger{private static int logNumber = 0;static public void InitializeLogging(){Console.WriteLine("日誌初始化");}static public void CloseLog(){Console.WriteLine("日誌關閉");}static public void LogMsg(string msg){Console.WriteLine("日誌編號為:" + logNumber + ":" + msg);}}
在用戶端,更不能建立Logger的執行個體,只能通過"類名.靜態方法名"調用方法。
static void Main(string[] args){Logger.InitializeLogging();Logger.LogMsg("日誌被記錄下了~~");Logger.CloseLog();}
總結:
○ 靜態變數屬於全域,位於棧上
○ 靜態建構函式只被觸發一次,無論是通過建構函式建立執行個體,還是給類的欄位或屬性賦值,靜態建構函式的觸發時機都在這些動作之前
○ 靜態類中不能有執行個體成員
以上內容是小編給大家介紹的C#靜態類,靜態建構函式,靜態變數的全部敘述,希望對大家有所協助!