C# static 干貨全解析


講解順序

  • 背景

  • 靜態字段

  • 靜態函數

  • 靜態方法

  • 疑問解答


  • 背景

    • static來源

    在編寫類的時候,有時候需要類里面的某個成員具有唯一性,也就是,對所有的對象都保持只有一個的狀態。比如創建個人信息,我們都是中國人,但總不能每個人都要保存一個中國人字段吧,用一個就夠了

    • static作用

    MSDN說:使用 static 修飾符聲明屬於類型本身而不是屬於特定對象的靜態成員。也就是說,用static修改的對象是一個類的全部成員,不屬於某個類特有的。比如,轎車有四個輪子,而不是某種轎車有四個輪子。

    • static特性

    1、訪問不需要聲明類對象。比如

    Console.Write();//Write()這就是一個靜態方法,不需要new Consolo();

    2、 static對象具有唯一性,無論是否產生了對象或無論產生了多少對象的情況下,某些特定的數據在內存空間里只有一份。也就是說,你無論new多少類成員,靜態變量只有一個,要變都變。


    靜態字段

    所謂靜態字段,也就是有static修改的字段啦(對,就是廢話o(∩_∩)oj_0028.gif )。

     

    • 作用

    無論創建多少對象,靜態字段代表的數據在內存空間中只有一個。比如說系統時間,無論你安裝了多少軟件,想知道現在幾點了,都只有一個參考值,如果你改變了這個時間,那么其他軟件獲取的時間也都改變了。(當然,只是舉例,具體咋訪問時間的,俺不管)。

    • 操作順序

    靜態字段是在類操作(實例化、調用靜態方法等)的時候第一個被實例化的對象。第二個是靜態構造函數,而且他倆都只能被調用一次。

    • 特性

    1. 因為靜態成員本身就是為了全局唯一性而生的,當然靜態成員在整個函數內部相當於了全局變量。
    2. 靜態成員只能被初始化一次,就是在第一次對這個類進行操作的時候創建。其他對整個類進行操作的時候,因為靜態成員已經有了,自然不會再創建。(就是給菜鳥寫的廢話,不然很多人會有疑問,比如我。)
    • 舉例

    無標題2

    ·如上圖,每次創建實例的時候,構造函數對兩個字段進行+1,但是結果不一樣,這就是static修飾的字段的唯一性

     


    靜態構造函數

    • 作用

    靜態構造函數一般用來初始化靜態變量,不會初始化非靜態變量;但是因為非靜態構造函數也能操作靜態變量,所以就比較少用靜態構造函數了。

    • 操作順序

    無論對類進行何種操作,靜態構造函數總是除了靜態字段以外第一個被操作的方法,比非靜態參數、非靜態構造函數都要提前。

    • 特性
    1. 只能操作靜態成員,因為非靜態成員需要實體引用。
    2. 整個生命周期只會運行一次,且不可被調用。
    3. 靜態構造函數不能有修飾符,因為只有系統才能調用,有沒有public都沒用;它也不能有輸入參數。
    4. 如果類里面含有Main方法,則先執行靜態構造函數;

     

    • 舉例
    class A { public static int X; static A() { X = B.Y + 1; } } class B { public static int Y = A.X +1; static B() { } static void Main(string[] args) { Console.WriteLine(string.Format("Y={0}, X={1}", B.Y, A.X));//Y=2, X=1;
     Console.ReadLine(); } }

    這是網上一個很有名的static的例子,如果不看答案,能夠算出來才是本事。

    1. 首先,Main()方法在B類里面,所以需要先調用B類。

    2. 進入B類,先對靜態字段Y分配空間,並默認賦值為0;注意,在這里Y已經初始化好了。

    3. 因為Y=A.X+1;所以操作A類的靜態字段,現在進入A類。

    4. 同樣的,先對A類的X分配空間並賦值為0。然后X=B.Y+1,B.Y已經存在了,為0,所以X=B.Y+1執行完后,X = 1。

    5. 調用A的靜態構造函數。

    6. 完成Y的賦值,Y=A.X + 1,Y=2。

    7. 調用B的靜態構造函數。

    8. 這時才會調用Main()方法,因為A.X,B.Y都完成了初始化並賦值,所以直接寫出答案。

    能夠將完整的順序描述出來,static一般的面試題都難不住你了(我的意思是我很牛j_0015.gif掰)


    靜態方法

    • 應用

    靜態方法一般用於頻繁調用又不經常修改的地方。比如工具庫方法、不需要實例化的方法、與具體業務無關,執行比較頻繁,用的地方多的方法等。當然,這個特性也是因為靜態方法無法被繼承,無法進行擴展有關。

    • 操作順序

    靜態方法會在靜態字段、靜態構造函數都操作后才能被調用。

    • 特性

    1. 靜態方法調用時不需要實例化類。
    2. 靜態方法只能引用靜態方法、字段、屬性。靜態方法里不能有非靜態變量。

    3. 靜態方法一經調用,就不能銷毀,除非整個應用程序域都結束了。所以靜態函數不能太多,否則一直占有內存。

    4. 因為靜態方法不能訪問非靜態變量,所以與非靜態方法耦合度較低,有利於代碼的修改。

    5. 靜態方法的執行效率比非靜態方法要高,但是因為其一直占用內存不能被銷毀,所以不能頻繁使用靜態方法。


    疑問解答

  • 靜態變量與非靜態變量最大的區別是什么?

    最大的區別在於內存的位置。靜態變量的內存是在程序開始執時變量就占用了內存,直到整個程序結束時變量才釋放內存. 非靜態變量是在程序運行到該步的時候分配內存,並在執行完后自動銷毀。所以:靜態變量的值只會初始化一次,后面每次訪問,都是上次處理過的值。

  • 為什么靜態變量不需要實例化就能訪問。

    因為類在初始化的時候,就已經為靜態變量分配好了內存空間,不需要實例化就能准確找到它們的位置;而非靜態成員必須在實例化類對象以后,才能確定它們的內存位置;因此也有這樣的說法,靜態成員是屬於類,而非靜態成員屬於類的對象

    為什么靜態方法里面不能訪問非靜態變量,也不能創建非靜態變量?

  • 因為非靜態變量需要實例化才能確認其內存中的位置,才能調用,而靜態函數是不需要實例化的,所以靜態方法不能使用

  • 為什么方法內部不能聲明靜態變量?

    因為靜態變量是類所有實例的共用變量,也就是在該類的范疇內是個全局變量。而如果在方法內部定義靜態變量,則會導致定義的靜態變量是一個局部變量,如此定義自然會出錯。

  • 靜態成員的生命周期

    靜態成員的生命周期是整個應用程序域的生存周期.也就是從操作含有靜態成員的類開始,一直到整個應用程序結束。


  • 以上信息都是我參考無數資料自己整理的,當然有可能出現一些錯誤,歡迎大嬸們指正,我會努力修改好,讓這篇文章作為一篇優秀的static參考資料。


    免責聲明!

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



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