項目中靜態和非靜態常被用到,什么時候需要用靜態的,什么時候需要使用非靜態,以及他們的區別是什么?
一、概述
靜態和非靜態的不同地方,就是靜態從程序一啟動就會一直占用內存,而非靜態只有在實例化的時候才會分配內存,每實例化一次對象都會重新分配一次內存。比如數據庫連接類,因為經常使用到,所以使用Static,定義成靜態類是最合適的。如果定義成非靜態方法,每次調用的時候都會實例化,這樣占用內存就會非常大。再比如登錄后台的方法,只在登陸的時候調用一次登錄方法,定義成非靜態方法是比較合適的。總之就是經常被調用的就用靜態的,反之使用非靜態。現在好多公司的項目都會使用靜態,內存換時間也是一種方式。畢竟目前增加內存的方式也有很多方式,而且成本也可以接受,只希望程序處理時間縮短,增加用戶體驗。
二、靜態類
靜態類和非靜態類的重要區別在於靜態類不能實例化,也就是說靜態類不能通過new創建靜態類型的實例。在聲明一個類時使用static關鍵詞有兩方面的含義:防止程序員實例化該靜態類,防止在靜態類里面定義所有的實例字段和方法。
非靜態類可以包含靜態的方法、字段、屬性或事件。即使沒有創建類的實例,也可以調用該類中的靜態成員。
1、靜態類的主要特征:
(1)僅包括靜態成員;
(2)無法實例化;
(3)靜態類有抽象類和密封類的特點,無法被實例化和無法被繼承;
(4)不能包括實例構造函數;
2、靜態類的構造函數解析
靜態構造函數是C#的一個新特性,其實好像很少用到。不過當我們想初始化一些靜態變量的時候就需要用到它了。這個構造函數是屬於類的,而不是屬於哪個實例的,就是說這個構造函數只會執行一次。靜態構造函數由.NET自動調用。
(1)靜態構造函數既沒有訪問修飾符,也沒有參數。因為是.NET調用的,所以像public和private等修飾符就沒有意義了。
(2).NET將自動調用靜態構造函數來初始化類,也就是說我們無法直接調用靜態構造函數,也就無法控制什么時候執行靜態構造函數了。
(3)一個類只能有一個靜態構造函數。
(4)如果沒有寫靜態構造函數,而類中包含帶有初始值設定的靜態成員,那么編譯器會自動生成默認的靜態構造函數。
3、靜態類的生命周期生命周期
當加載引用靜態類的程序時,.NET Framework 公共語言運行時 (CLR) 將加載該靜態類的類型信息,程序不能指定加載靜態類的確切時間。但是,可以保證在程序中首次引用該類前加載該類,初始化該類的字段並調用其靜態構造函數。 靜態構造函數僅調用一次,在程序駐留的應用程序域的生存期內,靜態類一直保留在內存中。也就是說,當頁面第一次被訪問的時候,相當於頁面被構造,靜態變量被靜態構造器初始化,然后再次訪問這個頁面的時候,雖然非靜態資源重新被構造,但是此時靜態資源並不被重新構造並一直存在。

public static class StaticStudent { private static string _name; private static int _age; static StaticStudent() { } public static string Name { get { return _name; } set { _name = value; } } public static int Age { get { return _age; } set { _age = value; } } }
三、靜態成員
1、靜態成員的特性
(1)靜態成員只被創建一次,所以靜態成員只有一份,實例成員有多少個對象,就有多少份。
(2)成員需要被共享的時候,方法需要被反復調用的時候,就可以把這些成員定義為靜態成員。
(3)在靜態方法中,不能直接調用實例成員,因為靜態方法被調用的時候,對象還有可能不存在。
(4)this/base 關鍵字在靜態方法中不能使用,因為有可能對象還不存在。
(5)在實例方法中,可以調用靜態成員,因為這個時候靜態成員肯定存在。
(6)非靜態類可以包含靜態的方法、字段、屬性或事件;
(7)一個非靜態類既有靜態成員也有實例成員,無論對一個類創建多少個實例,它的靜態成員都只有一個副本;
(8)靜態方法只能被重載,而不能被重寫,因為靜態方法不屬於類的實例成員;
(9)靜態類不能夠被繼承,原因你可以理解為靜態類被編譯后其實就是抽象類和密封類,也可以這樣理解:繼承后 實例化對象的時候會先初始化基類構造函數 而基類沒有非靜態構造函數。
(10)靜態類不能實現接口。這時你會問我靜態類被編譯的結果是abstract和sealed類,接口是abstract類,這並沒有影響到方法的實現啊。舉個例子我們定義一個靜態類,我們知道在一靜態類中是不能定義實例化的成員的(比如實例化的方法)。一個類實現一個接口必須要用實例的方法來實現接口中的定義的契約,這個與上面的矛盾。
(11)靜態類不能被派生,原因是靜態類只能從System.Object派生,派生繼承是OO的,靜態是反OO的。
2、生命周期
靜態成員在第一次被訪問之前並且在調用靜態構造函數(如有存在)之前進行初始化,此后一直保持在內存中,直到應用程序域的生命周期結束。

public class Student { private static string _name; private int _age; public Student(string name,int age) { this.Age = age; Name = name; } public static string Name { get { return _name; } set { _name = value; } } public int Age { get { return _age; } set { _age = value; } } public static void StaticPrint() { Console.WriteLine("靜態方法{0}",Name); } public void Print() { Console.WriteLine("非靜態方法{0} {1}",Name,Age); } }