【從UnityURP開始探索游戲渲染】專欄-直達
- 實例構造函數(Instance Constructor)不能標記為
static
- 但C#提供了一種特殊的? 靜態構造函數(Static Constructor)專門用于初始化靜態成員。
- 下面依次介紹他們:
1. ?實例構造函數(不能標記為static
)?
- 用于初始化?實例成員?。
- 每次創建類的新實例時調用。
- ?不允許?使用
static
關鍵字修飾。
csharp
public class MyClass {
// 實例構造函數(正確)public MyClass() {
// 初始化實例成員}
// ? 錯誤:實例構造函數不能標記為static// public static MyClass() { ... }
}
2. ?靜態構造函數(隱式static
)?
- 用于初始化?靜態成員?。
- 在整個程序生命周期內?最多自動調用一次?(在類首次被使用時觸發)。
- 必須滿足以下語法:
- 使用
static
關鍵字。 - ?不能有訪問修飾符?(如
public
、private
),默認為private
。 - ?不能有參數?。
- 類中最多只能有一個靜態構造函數。
- 使用
csharp
public class MyClass {static MyClass() {
// 初始化靜態成員}
}
關鍵總結
特性 | 實例構造函數 | 靜態構造函數 |
---|---|---|
?關鍵字? | 無static (不能標記為static ) | 必須使用static |
?調用時機? | 每次創建實例時調用 | 類首次使用時自動調用(僅一次) |
?參數? | 可以有參數 | ?不能有參數? |
?訪問修飾符? | 支持(如public 、private ) | ?不允許?(默認為private ) |
?用途? | 初始化實例成員 | 初始化靜態成員 |
何時使用靜態構造函數?
當類中的靜態成員(如靜態字段)需要復雜的初始化邏輯(例如讀取配置文件或構建靜態數據結構)時使用:
csharp
public class Logger {public static string LogPath { get; }static Logger() {LogPath = LoadLogPathFromConfig();// 復雜初始化}private static string LoadLogPathFromConfig() { ... }
}
錯誤示例
csharp
public class MyClass {
// ? 編譯錯誤:實例構造函數不能是靜態的public static MyClass() { ... }// ? 編譯錯誤:靜態構造函數不能有訪問修飾符public static MyClass() { ... }// ? 編譯錯誤:靜態構造函數不能有參數static MyClass(string param) { ... }
}
?結論?:
普通構造函數(實例構造函數)?不能?標記為static
,但C#提供了專門的?靜態構造函數語法?(使用static
關鍵字且無訪問修飾符/參數)來初始化靜態成員。兩者設計目的和調用機制完全不同。
使用示例
- 基礎使用場景(初始化靜態成員)靜態構造函數常用于初始化類的靜態字段,例如統計類實例數量:
csharp
public class Logger
{public static int InstanceCount;public static string LogDirectory;static Logger(){InstanceCount = 0;LogDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),"AppLogs");Directory.CreateDirectory(LogDirectory);}
}
-
當首次訪問Logger類時,會自動創建日志目錄并初始化計數器。
-
配置加載示例適合加載只需執行一次的配置文件:
csharp
public class AppConfig
{public static readonly Dictionary<string, string> Settings;static AppConfig(){Settings = new Dictionary<string, string>();var config = ConfigurationManager.AppSettings;foreach (var key in config.AllKeys){Settings.Add(key, config[key]);}}
}
-
該構造函數在程序首次使用配置時自動加載。
-
復雜初始化場景處理相互依賴的靜態字段初始化:
csharp
public class A
{public static int X = B.Y + 1;static A() { }
}public class B
{public static int Y = A.X + 1;static B() { }
}
- 運行時能正確處理這種交叉引用關系。
關鍵特性說明:
- 每個類只能有一個靜態構造函數
- 不能包含訪問修飾符或參數
- 在以下情況自動調用:創建第一個實例前訪問任何靜態成員前
- 執行時機由CLR控制,不可顯式調用
特殊注意事項:
- 當同時存在靜態構造函數和靜態字段初始化時,字段初始化器會先執行。例如:
csharp
public class Test
{public static Test t = new Test();static Test() => Console.WriteLine("靜態構造");public Test() => Console.WriteLine("實例構造");
}
// 輸出順序:實例構造 -> 靜態構造
典型應用場景:
- 初始化靜態字典/集合
- 注冊事件處理器
- 加載本地化資源
- 建立數據庫連接池
注意
- 靜態構造函數中應避免拋出異常,否則會導致TypeInitializationException
【從UnityURP開始探索游戲渲染】專欄-直達
(歡迎點贊留言探討,更多人加入進來能更加完善這個探索的過程,🙏)