構造函數(C# 編程指南)
- 構造函數概述
- 使用構造函數
- 構造函數分類
- 實例構造函數
- 私有構造函數
- 靜態構造函數
構造函數概述
每當創建類或結構時,將會調用其構造函數。 類或結構可能具有采用不同參數的多個構造函數。 使用構造函數,程序員能夠設置默認值、限制實例化,並編寫靈活易讀的代碼。 有關詳細信息和示例,請參閱使用構造函數和實例構造函數。
構造函數語法
構造函數是一種方法,其名稱與其類型的名稱相同。 其方法簽名僅包含方法名稱和其參數列表;它不包含返回類型。 以下示例演示一個名為 Person
的類的構造函數。
構造函數分類
構造函數可分為:實例構造函數,靜態構造函數,私有構造函數
實例構造函數分為:有參數構造函數、無參構造函數
當類中已經聲明了有參數構造函數,那么必須寫一個無參構造函數,因為此時系統不能自動生成無參構造函數
靜態構造函數:只有一個無參數靜態構造函數
實例構造函數
如果沒有為類提供構造函數,則 C# 將默認創建一個構造函數,該函數會實例化對象並將成員變量設置為默認值,如 C# 類型的默認值中所列。 如果沒有為結構提供構造函數,C# 將依賴於隱式無參數構造函數,自動將每個字段初始化為其默認值。 有關詳細信息和示例,請參閱實例構造函數
下面的示例說明包含兩個類構造函數的類:一個不帶參數,另一個帶有兩個參數 初始化類。
class Coords { public int x, y; // Parameterless constructor. public Coords() { x = 0; y = 0; } // A constructor with two parameters. public Coords(int x, int y) { this.x = x; this.y = y; } public override string ToString() { return $"({x},{y})"; } } class MainClass { static void Main() { var p1 = new Coords(); var p2 = new Coords(5, 3); Console.WriteLine($"Coords #1 at {p1}"); Console.WriteLine($"Coords #2 at {p2}"); Console.ReadKey(); } } /* Output: Coords #1 at (0,0) Coords #2 at (5,3) */
私有構造函數
類成員有private修飾符,就不允許在類范圍以外訪問這個類成員。對類構造函數應用private修飾符時,則禁止外部類創建該類的實例。
類是通過無參構造函數實例化的。對類構造函數應用private修飾符時,防止從外部實例化類。既然不能實例化,那么這個類還有什么用處?但實際上這是一個功能極其強大的特性。
雖然私有構造函數不允許外部方法實例化這個類,但卻允許此類中的公共方法(有時也稱為工廠方法,factory method)創建對象。也就是說,類可以創建自身的實例、控制外界對它的訪問,以及控制創建的實例個數
靜態構造函數
類的靜態構造函數用於 初始化任何類本身的靜態數據 ,所以不允許有訪問修飾符,靜態構造函數是無參構造函數, 將在創建第一個實例或引用任何靜態成員之前自動調用靜態構造函數。
類的初始化過程: 初始值設定項>靜態構造函數>實例構造函數
靜態構造函數具有以下屬性:
-
靜態構造函數不使用訪問修飾符或不具有參數。
-
類或結構只能有一個靜態構造函數。
-
靜態構造函數不能繼承或重載。
-
靜態構造函數不能直接調用,並且僅應由公共語言運行時 (CLR) 調用。 可以自動調用它們。
-
用戶無法控制在程序中執行靜態構造函數的時間。
-
自動調用靜態構造函數。 將在創建第一個實例或引用任何靜態成員之前初始化類。 靜態構造函數在實例構造函數之前運行。 調用(而不是分配)分配給事件或委托的靜態方法時,將調用類型的靜態構造函數。 如果靜態構造函數類中存在靜態字段變量初始值設定項,它們將以在類聲明中顯示的文本順序執行。 初始值設定項緊接着執行靜態構造函數之前運行。
-
如果未提供靜態構造函數來初始化靜態字段,會將所有靜態字段初始化為其默認值,如 C# 類型的默認值中所列。
-
如果靜態構造函數引發異常,運行時將不會再次調用該函數,並且類型在應用程序域的生存期內將保持未初始化。 大多數情況下,當靜態構造函數無法實例化一個類型時,或者當靜態構造函數中發生未經處理的異常時,將引發 TypeInitializationException 異常。 對於未在源代碼中顯式定義的靜態構造函數,故障排除可能需要檢查中間語言 (IL) 代碼。
-
靜態構造函數的存在將防止添加 BeforeFieldInit 類型屬性。 這將限制運行時優化。
-
聲明為
static readonly
的字段可能僅被分配為其聲明的一部分或在靜態構造函數中。 如果不需要顯式靜態構造函數,請在聲明時初始化靜態字段,而不是通過靜態構造函數,以實現更好的運行時優化。 -
運行時在單個應用程序域中多次調用靜態構造函數。 該調用是基於特定類型的類在鎖定區域中進行的。 靜態構造函數的主體中不需要其他鎖定機制。 若要避免死鎖的風險,請勿阻止靜態構造函數和初始值設定項中的當前線程。 例如,不要等待任務、線程、等待句柄或事件,不要獲取鎖定,也不要執行阻止並行操作,如並行循環、
Parallel.Invoke
和並行 LINQ 查詢
c# 為什么結構中不能有實例字段初始設定值項
結構式數值類型。在