靜態(static)是C#中一個重要的關鍵字,它可以應用于類、方法、屬性和字段。
靜態類
靜態類的特點:
- 不能實例化
- 只能包含靜態成員
- 密封的(sealed),不能被繼承
應用場景:
- 工具類/輔助類
- 數學計算類:如Math類
- 擴展方法、全局訪問等
擴展方法
擴展方法必須寫在非泛型的靜態類中
對int類型進行擴展,添加一個Divide方法,返回double類型
this 后面跟類型和參數名稱,為要進行擴展的類
public static class ExtendMethod{public static double Divide(this int a, int b){return a*1.0 / b;}}
使用
靜態類
除擴展方法外,其他類中,除非特殊需要一般不直接寫為靜態類,因為靜態類中的,方法、屬性、成員必須是靜態的。
public static class StringHelper
{ public static string Reverse(string input){char[] charArray = input.ToCharArray();Array.Reverse(charArray);return new string(charArray);}
}// 使用
var result = StringHelper.Reverse("hello");
靜態方法
- 不依賴于實例對象
- 單例模式的實力獲取方法
在類中添加一個生成單例的方法,當然也運行通過new的方式創建,此時非單例
public class Logger{private static Logger _instance;private static object _lock = new object();public static Logger GetInstance(){lock (_lock){if (_instance == null){_instance = new Logger();}return _instance;}}// 實例方法public void Log(string message){Console.WriteLine(message);}}
使用
static void Main(string[] args){Logger logger = Logger.GetInstance();logger.Log("Test message");Console.ReadLine();}
靜態屬性
- 共享數據,全局配置
- 資源計數
- 單例實例訪問
private static object _syncObj = new object();private static KvPLC _instance = null;public static KvPLC KvInstance //單例對象{get{lock (_syncObj){if (_instance == null){_instance = new KvPLC();}}return _instance;}}
靜態字段
- 共享數據、緩存常用數據
- 計數器
- 只讀常量(通常與const或readonly一起使用)
統計User類的用戶數量
public class User{private static int _userCount = 0;public User(){_userCount++;}public static int TotalUserCount=>_userCount;}
使用
static void Main(string[] args){var user1 = new User();var user2 = new User();//總用戶數:2Console.WriteLine($"總用戶數:{User.TotalUserCount}");Console.ReadLine();}
優點:
- 無需實例化即可使用, 全局可訪問(需謹慎使用)
缺點:
-
可能導致代碼緊耦合,難以進行單元測試
-
過度使用可能導致"上帝對象"問題
-
線程安全問題(需要特別注意同步)
靜態屬性和靜態字段
訪問控制
靜態字段
- 直接暴露數據,無訪問控制邏輯
- 若為public,外部可直接修改值,風險較高
public static class Counter {public static int Count; // 直接暴露
}// 外部可直接修改
Counter.Count = 100; // 無任何驗證邏輯
- 靜態屬性
- 通過get/set控制訪問
- 可添加驗證邏輯、延遲加載、線程同步等
驗證邏輯
public static class Counter {private static int _count;public static int Count {get => _count;set {if (value >= 0) // 添加驗證_count = value;}}
}Counter.Count = -5; // 賦值無效,值不會被修改
延遲加載
public static class LazyData {private static Data _data;public static Data Data {get {if (_data == null) _data = LoadData();return _data;}}private static Data LoadData() { /*...*/ }
}
線程安全
public static class ThreadSafeCounter {private static int _count;private static object _lock = new();public static int Count {get { lock(_lock) return _count; }set { lock(_lock) _count = value; }}
}
初始化方式
靜態字段
- 支持直接初始化或通過靜態構造函數
- 可聲明為readonly(只讀)
public static class Constants {public static readonly int MaxRetries = 3; // 運行時初始化public const string AppName = "MyApp"; // 編譯時常量
}
靜態屬性
- 初始化需通過訪問器或靜態構造函數
- 不可直接使用readonly,但可通過私有set實現只讀
public static class Config {public static string Environment { get; } = "Production"; // 只讀屬性public static int Timeout { get; private set; } = 30; // 限制外部修改
}
總結
-
簡單數據存儲 → 優先使用private static field + public static property
-
需要控制訪問或擴展邏輯 → 必須使用靜態屬性
-
常量數據 → 使用public const或public static readonly字段
-
線程共享數據 → 通過屬性添加同步機制