在C#中,靜態(tài)表示無(wú)法實(shí)例化的內(nèi)容。您不能創(chuàng)建靜態(tài)類(lèi)的對(duì)象,也不能使用對(duì)象訪問(wèn)靜態(tài)成員。
類(lèi)、變量、方法、屬性、運(yùn)算符、事件和構(gòu)造函數(shù)可以使用static修飾符關(guān)鍵字定義為靜態(tài)的。
在類(lèi)名之前和訪問(wèn)修飾符之后應(yīng)用static修飾符,使類(lèi)成為靜態(tài)的。下面定義了一個(gè)具有靜態(tài)字段和方法的靜態(tài)類(lèi)。
public static class Calculator { private static int _resultStorage = 0; public static string Type = "Arithmetic"; public static int Sum(int num1, int num2) { return num1 + num2; } public static void Store(int result) { _resultStorage = result; } }
上面的Calculator類(lèi)是靜態(tài)的。它的所有成員也是靜態(tài)的。
您不能創(chuàng)建靜態(tài)類(lèi)的對(duì)象。因此,可以使用類(lèi)名 ClassName.MemberName 直接訪問(wèn)static類(lèi)的成員,如下所示。
class Program { static void Main(string[] args) { var result = Calculator.Sum(10, 25); //調(diào)用靜態(tài)方法 Calculator.Store(result); var calcType = Calculator.Type; // 訪問(wèn)靜態(tài)變量 Calculator.Type = "Scientific"; // 給靜態(tài)變量賦值 } }
靜態(tài)類(lèi)無(wú)法實(shí)例化。
靜態(tài)類(lèi)的所有成員必須是靜態(tài)的。否則,編譯器將給出錯(cuò)誤。
靜態(tài)類(lèi)可以包含靜態(tài)變量,靜態(tài)方法,靜態(tài)屬性,靜態(tài)運(yùn)算符,靜態(tài)事件和靜態(tài)構(gòu)造函數(shù)。
靜態(tài)類(lèi)不能包含實(shí)例成員和構(gòu)造函數(shù)。
索引器和析構(gòu)器不能是靜態(tài)的
var不能用于定義靜態(tài)成員。您必須在static關(guān)鍵字之后顯式指定成員類(lèi)型。
靜態(tài)類(lèi)是密封類(lèi),因此不能繼承。
靜態(tài)類(lèi)不能從其他類(lèi)繼承。
可以使用 ClassName.MemberName(即:類(lèi)名.成員名) 訪問(wèn)靜態(tài)類(lèi)成員。
靜態(tài)類(lèi)在程序所在的應(yīng)用程序域的整個(gè)生命周期內(nèi)都將保留在內(nèi)存中。
普通類(lèi)(非靜態(tài)類(lèi))可以包含一個(gè)或多個(gè)靜態(tài)方法,字段,屬性,事件和其他非靜態(tài)成員。
使用一些靜態(tài)成員定義非靜態(tài)類(lèi),而不是將整個(gè)類(lèi)聲明為靜態(tài)類(lèi),這是比較實(shí)用的。
可以使用 static 關(guān)鍵字定義非靜態(tài)類(lèi)中的靜態(tài)字段。
非靜態(tài)類(lèi)的靜態(tài)字段在所有實(shí)例之間共享。因此,一個(gè)實(shí)例所做的更改將反映在其他實(shí)例中。
public class StopWatch { public static int InstanceCounter = 0; // 實(shí)例構(gòu)造函數(shù) public StopWatch() { } } class Program { static void Main(string[] args) { StopWatch sw1 = new StopWatch(); StopWatch sw2 = new StopWatch(); Console.WriteLine(StopWatch.NoOfInstances); //2 StopWatch sw3 = new StopWatch(); StopWatch sw4 = new StopWatch(); Console.WriteLine(StopWatch.NoOfInstances);//4 } }
您可以在非靜態(tài)類(lèi)中定義一個(gè)或多個(gè)靜態(tài)方法??梢栽诓粍?chuàng)建對(duì)象的情況下調(diào)用靜態(tài)方法。您不能使用非靜態(tài)類(lèi)的對(duì)象調(diào)用靜態(tài)方法。
靜態(tài)方法只能調(diào)用其他靜態(tài)方法并訪問(wèn)靜態(tài)成員。您不能在靜態(tài)方法中訪問(wèn)類(lèi)的非靜態(tài)成員。
class Program { static int counter = 0; string name = "Demo Program"; static void Main(string[] args) { counter++; // 可以訪問(wèn)靜態(tài)字段 Display("Hello World!"); // 可以調(diào)用靜態(tài)方法 name = "New Demo Program"; //錯(cuò)誤:無(wú)法訪問(wèn)非靜態(tài)成員 SetRootFolder("C:\MyProgram"); //錯(cuò)誤:無(wú)法調(diào)用非靜態(tài)方法 } static void Display(string text) { Console.WriteLine(text); } public void SetRootFolder(string path) { } }
靜態(tài)方法可以在返回類(lèi)型之前使用 static 關(guān)鍵字定義,然后在訪問(wèn)修飾符之后定義。
靜態(tài)方法可以重載,但不能被重寫(xiě)。
靜態(tài)方法可以包含局部靜態(tài)變量。
靜態(tài)方法不能訪問(wèn)或調(diào)用非靜態(tài)變量,除非它們被顯式地作為參數(shù)傳遞。
非靜態(tài)類(lèi)可以包含無(wú)參數(shù)靜態(tài)構(gòu)造函數(shù)??梢允褂胹tatic關(guān)鍵字定義它,而沒(méi)有訪問(wèn)修飾符,例如 public,private和protected。
以下示例演示了靜態(tài)構(gòu)造函數(shù)和實(shí)例構(gòu)造函數(shù)之間的區(qū)別。
public class StopWatch { // 靜態(tài)構(gòu)造函數(shù) static StopWatch() { Console.WriteLine("調(diào)用了靜態(tài)構(gòu)造函數(shù)"); } // 實(shí)例構(gòu)造函數(shù) public StopWatch() { Console.WriteLine("調(diào)用了實(shí)例構(gòu)造函數(shù)"); } // 靜態(tài)方法 public static void DisplayInfo() { Console.WriteLine("調(diào)用了DisplayInfo"); } // 實(shí)例方法 public void Start() { } // 實(shí)例方法 public void Stop() { } }
上面的非靜態(tài)類(lèi)StopWatch包含一個(gè)靜態(tài)構(gòu)造函數(shù),也包含一個(gè)非靜態(tài)構(gòu)造函數(shù)。
每當(dāng)使用靜態(tài)方法或首次創(chuàng)建實(shí)例時(shí),靜態(tài)構(gòu)造函數(shù)僅被調(diào)用一次。下面的示例顯示,在首次調(diào)用static方法時(shí),將調(diào)用static構(gòu)造函數(shù)。第二次再調(diào)用靜態(tài)方法將不會(huì)調(diào)用靜態(tài)構(gòu)造函數(shù)。
StopWatch.DisplayInfo(); // 此處調(diào)用靜態(tài)構(gòu)造函數(shù) StopWatch.DisplayInfo(); // 這里沒(méi)有調(diào)用構(gòu)造函數(shù)
已調(diào)用靜態(tài)構(gòu)造函數(shù)。 調(diào)用了DisplayInfo 調(diào)用了DisplayInfo
下面的示例顯示,首次創(chuàng)建實(shí)例時(shí)將調(diào)用靜態(tài)構(gòu)造函數(shù)。
StopWatch sw1 = new StopWatch(); // 首先是靜態(tài)構(gòu)造函數(shù),然后是實(shí)例構(gòu)造函數(shù) StopWatch sw2 = new StopWatch();// 只有實(shí)例構(gòu)造函數(shù)被調(diào)用 StopWatch.DisplayInfo();
調(diào)用了靜態(tài)構(gòu)造函數(shù) 調(diào)用了實(shí)例構(gòu)造函數(shù) 調(diào)用了實(shí)例構(gòu)造函數(shù) 調(diào)用了DisplayInfo
靜態(tài)構(gòu)造函數(shù)是使用 static 關(guān)鍵字定義的,沒(méi)有使用訪問(wèn)修飾符 public,private 或 protected。
非靜態(tài)類(lèi)可以包含一個(gè)無(wú)參數(shù)的靜態(tài)構(gòu)造函數(shù)。不允許使用參數(shù)化的靜態(tài)構(gòu)造函數(shù)。
靜態(tài)構(gòu)造函數(shù)將在生命周期內(nèi)僅執(zhí)行一次。因此,如果在多個(gè)地方都使用了一個(gè)類(lèi),則無(wú)法確定何時(shí)在應(yīng)用程序中調(diào)用它。
靜態(tài)構(gòu)造函數(shù)只能訪問(wèn)靜態(tài)成員。它不能包含或訪問(wèn)實(shí)例成員。
靜態(tài)成員存儲(chǔ)在內(nèi)存中稱(chēng)為“高頻堆”的特殊區(qū)域中。非靜態(tài)類(lèi)的靜態(tài)成員在該類(lèi)的所有實(shí)例之間共享。因此,一個(gè)實(shí)例所做的更改將反映在所有其他實(shí)例中。