程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#靜態類,靜態構造函數,靜態變量,

C#靜態類,靜態構造函數,靜態變量,

編輯:C#入門知識

C#靜態類,靜態構造函數,靜態變量,


本篇體驗靜態變量、靜態構造函數和靜態類。

 

  靜態變量

靜態變量位於棧上,它是一個全局變量,在編譯期就已經生成。

    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();
        }

 

 

總結:
○ 靜態變量屬於全局,位於棧上
○ 靜態構造函數只被觸發一次,無論是通過構造函數創建實例,還是給類的字段或屬性賦值,靜態構造函數的觸發時機都在這些動作之前
○ 靜態類中不能有實例成員

 

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved