靜態類與非靜態類基本相同,但存在一個區別:靜態類不能實例化。也就是說,不能使用 new 關鍵字建立靜態類類型的變量。由於沒有實例變量,因此要使用類名自己訪問靜態類的成員。函數
static class CompanyInfo { public static string GetCompanyName() { return "CompanyName"; } public static string GetCompanyAddress() { return "CompanyAddress"; } //... }
和全部類類型同樣,當加載引用靜態類的程序時,.NET Framework 公共語言運行時 (CLR) 將加載該靜態類的類型信息。程序不能指定加載靜態類的確切時間。可是,能夠保證在程序中首次引用該類前加載該類,並初始化該類的字段並調用其靜態構造函數。靜態構造函數僅調用一次,在程序駐留的應用程序域的生存期內,靜態類一直保留在內存中。對於只對輸入參數進行運算而不獲取或設置任何內部實例字段的方法集,靜態類能夠方便地用做這些方法集的容器。例如,在 .NET Framework 類庫中,靜態類 System.Math 包含的一些方法只執行數學運算,而無需存儲或檢索特定 Math 類實例特有的數據。性能
靜態類的主要特性:僅包含靜態成員。沒法實例化。是密封的。不能包含實例構造函數。建立靜態類(A)與建立僅包含靜態成員和私有構造函數的類(B)基本相同,私有構造函數阻止類被實例化。出現B這種狀況易選用A。spa
使用靜態類的優勢在於,編譯器可以執行檢查以確保不致偶然地添加實例成員。編譯器將保證不會建立此類的實利。debug
靜態類是密封的,所以不可被繼承。它們不能從除 Object 外的任何類中繼承。靜態類不能包含實例構造函數,但能夠包含靜態構造函數。若是非靜態類包含須要進行重要的初始化的靜態成員,也應定義靜態構造函數。對象
下面是一個靜態類的示例,它包含兩個在攝氏溫度和華氏溫度之間執行來回轉換的方法: public static class TemperatureConverter { public static double CelsiusToFahrenheit(string temperatureCelsius) { // Convert argument to double for calculations. double celsius = Double.Parse(temperatureCelsius); // Convert Celsius to Fahrenheit. double fahrenheit = (celsius * 9 / 5) + 32; return fahrenheit; } public static double FahrenheitToCelsius(string temperatureFahrenheit) { // Convert argument to double for calculations. double fahrenheit = Double.Parse(temperatureFahrenheit); // Convert Fahrenheit to Celsius. double celsius = (fahrenheit - 32) * 5 / 9; return celsius; } } class TestTemperatureConverter { static void Main() { Console.WriteLine("Please select the convertor direction"); Console.WriteLine("1. From Celsius to Fahrenheit."); Console.WriteLine("2. From Fahrenheit to Celsius."); Console.Write(":"); string selection = Console.ReadLine(); double F, C = 0; switch (selection) { case "1": Console.Write("Please enter the Celsius temperature: "); F = TemperatureConverter.CelsiusToFahrenheit(Console.ReadLine()); Console.WriteLine("Temperature in Fahrenheit: {0:F2}", F); break; case "2": Console.Write("Please enter the Fahrenheit temperature: "); C = TemperatureConverter.FahrenheitToCelsius(Console.ReadLine()); Console.WriteLine("Temperature in Celsius: {0:F2}", C); break; default: Console.WriteLine("Please select a convertor."); break; } // Keep the console window open in debug mode. Console.WriteLine("Press any key to exit."); Console.ReadKey(); } } /* Example Output: Please select the convertor direction 1. From Celsius to Fahrenheit. 2. From Fahrenheit to Celsius. :2 Please enter the Fahrenheit temperature: 20 Temperature in Celsius: -6.67 Press any key to exit. */
靜態成員blog
非靜態類能夠包含靜態的方法、字段、屬性或事件。即便沒有建立類的實例,也能夠調用該類中的靜態成員。始終經過類名而不是實例名稱訪問靜態成員。繼承
不管對一個類建立多少個實例,它的靜態成員都只有一個副本。事件
靜態方法和屬性不能訪問其包含類型中的非靜態字段和事件,而且不能訪問任何對象的實例變量(除非在方法參數中顯式傳遞)。內存
更常見的作法是聲明具備一些靜態成員的非靜態類,而不是將整個類聲明爲靜態類。靜態字段有兩個常見的用法:一是記錄已實例化對象的個數,二是存儲必須在全部實例之間共享的值。ci
靜態方法能夠被重載但不能被重寫,由於它們屬於類,不屬於類的任何實例。
雖然字段不能聲明爲 static const,但 const 字段的行爲在本質上是靜態的。這樣的字段屬於類型,不屬於類型的實例。所以,能夠同對待靜態字段同樣使用 ClassName.MemberName 表示法來訪問 const 字段。不須要對象實例。
C# 不支持靜態局部變量(在方法範圍內聲明的變量)。
經過在成員的返回類型以前使用 static 關鍵字能夠聲明靜態類成員,以下面的示例
public class Automobile { public static int NumberOfWheels = 4; public static int SizeOfGasTank { get { return 15; } } public static void Drive() { } public static event EventType RunOutOfGas; // Other non-static fields and properties... }
靜態成員在第一次被訪問以前而且在調用靜態構造函數(若有存在)以前進行初始化。若要訪問靜態類成員,應使用類名而不是變量名來指定該成員的位置,以下面的示例所示:
Automobile.Drive();
int i = Automobile.NumberOfWheels;
若是類包含靜態字段,請提供在加載類時初始化這些字段的靜態構造函數。
對靜態方法的調用以 Microsoft 中間語言 (MSIL) 生成調用指令,而對實例方法的調用生成 callvirt 指令,該指令還檢查 null 對象引用。可是,二者之間的性能差別在大多數時候並不明顯。
靜態類在內存中是一直有位置的;
2:非靜態類在實例化後是在內存中是獨立的,它的變量不會重複,在使用後會及時銷燬,因此不會出現未知
的錯誤。在C#中靜態成員是比較敏感的東西,在不是十分確認的狀況下不要使用;
3:建議更多地使用通常類(非靜態類)。