淺析C#靜態類,靜態建構函式,靜態變數_C#教程

來源:互聯網
上載者:User

靜態變數

靜態變數位於棧上,它是一個全域變數,在編譯期就已經產生。

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#靜態類,靜態建構函式,靜態變數的全部敘述,希望對大家有所協助!

聯繫我們

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