目錄
一、什么是靜態的?什么是常量?
1. ?靜態(Static)?
2. ?常量(const)?
二、類中的靜態成員有什么用?
1. ?共享數據
2. ?工具方法與全局配置
3. ?單例模式
三、靜態類和靜態成員方法的介紹
1. ?靜態類(Static Class)?
2. ?靜態構造函數(Static Constructor)?
3. ?靜態方法的限制
四、對比總結
1. ?靜態成員 vs 常量(const)?
2. ?靜態類 vs 普通類
3. ?使用場景
注意事項
前言:代碼中的“共享經濟”與“不變法則”?
????????有沒有想過,如何讓一個類的所有實例共享同一份數據?或者怎樣創建一種無需實例化就能調用的“工具包”方法?
????????在C#的世界里,?靜態成員就像魔法般的全局變量,而常量則是刻在代碼石碑上的永恒法則。它們一個靈活善變(但需謹慎),一個堅守初心(絕不妥協)。
????????本文將揭秘靜態類的“禁欲系”設計、靜態構造函數的幕后初始化大法,并帶你理清靜態成員與常量的愛恨糾葛——從此告別重復代碼,讓你的程序優雅如詩!
一、什么是靜態的?什么是常量?
1. ?靜態(Static)?
????????靜態是C#中用于描述類級別成員的關鍵字。靜態成員(如靜態字段、方法、屬性)屬于類本身而非類的實例,所有實例共享同一份靜態成員。
- ?內存分配:靜態成員在程序啟動時分配內存,生命周期與應用程序一致。
- ?訪問方式:直接通過類名訪問,無需實例化對象。
記住!!!
程序是不能無中生有的
我們要使用的對象 變量 函數 都是要在內存中分配空間的
之所以要實例化對象 目的就是要分配內存空間,在程序中 產生一個抽象的對象靜態成員的特點
程序開始運行時 就會分配內存空間 所以我們可以直接使用
靜態成員和程序同生共死
只要使用了他 直到程序結束時 內存空間才會被釋放
所以每個靜態成員都有屬于自己的唯一一個小房間
這讓靜態成員便有了唯一性
在任何地方使用 都是使用小房間里面的內容 修改的也是房間里面的內容
2. ?常量(const)?
????????常量是通過const
關鍵字定義的不可修改的編譯時常量。
- ?內存分配:值在編譯時確定并嵌入到IL代碼中。
- ?不可變性:必須在聲明時賦值,且只能為基本類型(如
int
,?string
)或null
。
// 靜態字段 vs 常量
public class Config {public static string Environment = "Production"; // 靜態字段(可修改)public const int MaxRetryCount = 3; // 常量(不可修改)
}
const (常量)可以理解為特殊的靜態static
相同點:
他們都可以通過類名點出使用
不同點
1.const 必須初始化,不能修改 static 沒有這個限制
2.const 只能修飾變量,static可以修飾很多
3.const一定是寫在訪問修飾符后面的,static沒有這個要求?
二、類中的靜態成員有什么用?
1. ?共享數據
????????靜態成員用于存儲所有實例共享的數據。例如,統計類的實例總數:
public class User {public static int UserCount = 0; // 所有實例共享public User() {UserCount++;}
}Console.WriteLine(User.UserCount); // 直接通過類訪問
2. ?工具方法與全局配置
????????將無需實例化的工具方法或全局配置定義為靜態成員:
public class MathUtils {public static double PI = 3.1415926;public static int Add(int a, int b) => a + b;
}
Console.WriteLine(MathUtils.Add(2, 3)); // 直接調用靜態方法
3. ?單例模式
????????通過靜態成員實現單例(確保類只有一個實例):
public class Singleton {private static Singleton _instance;public static Singleton Instance => _instance ??= new Singleton();private Singleton() { }
}
三、靜態類和靜態成員方法的介紹
1. ?靜態類(Static Class)?
- ?定義:用
static
修飾的類,不能實例化,只能包含靜態成員。 - ?用途:封裝工具類或擴展方法容器。
public static class StringExtensions {public static string ToTitleCase(this string input) {return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(input);}
}string name = "john doe";
Console.WriteLine(name.ToTitleCase()); // 輸出 "John Doe"
注意:直接類名然后點出來使用 里面的方法
2. ?靜態構造函數(Static Constructor)?
- ?作用:初始化靜態字段或執行一次性的靜態初始化邏輯。
- ?調用時機:在類首次被訪問(如創建實例、調用靜態方法)時自動執行。
注:這里的創造實例是指的是點出內部已經給你創造好的實例。你自己是無法new的。
????????看如下代碼:
public class Singleton {// 靜態成員管理唯一實例private static Singleton _instance;public static Singleton Instance => _instance ??= new Singleton();// 私有構造函數,禁止外部 newprivate Singleton() { }
}// 正確!通過靜態屬性訪問唯一實例
var instance = Singleton.Instance;
這份代碼是靜態構造函數的一個實際應用:?
????????這段代碼定義了一個?Logger
?類,其核心功能是初始化日志文件的存儲目錄。通過靜態成員和靜態構造函數的設計,確保日志目錄在程序運行期間只創建一次,且無需手動初始化。
public class Logger {public static string LogDirectory;static Logger() {LogDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");Directory.CreateDirectory(LogDirectory);}
}
注意:這個主要是用來初始化,做一些配置什么的
3. ?靜態方法的限制
- 不能訪問實例成員(非靜態字段、方法),只能訪問其他靜態成員。
- 不能使用
this
關鍵字。?
四、對比總結
1. ?靜態成員 vs 常量(const)?
?特性 | ?靜態成員 | ?常量(const)? |
---|---|---|
內存分配 | 運行時分配 | 編譯時嵌入到IL代碼 |
可修改性 | 可修改(除非是readonly ) | 不可修改 |
類型限制 | 無限制 | 僅支持基本類型或null |
初始化時機 | 靜態構造函數或聲明時 | 必須在聲明時賦值 |
2. ?靜態類 vs 普通類
?特性 | ?靜態類 | ?普通類 |
---|---|---|
實例化 | 不可實例化 | 可以實例化 |
成員類型 | 僅包含靜態成員 | 可包含靜態和實例成員 |
繼承 | 不能繼承或被繼承 | 支持繼承 |
3. ?使用場景
- ?靜態成員:共享數據、工具方法、全局配置。
- ?靜態類:工具類、擴展方法容器、單例模式。
- ?常量:固定不變的值(如數學常數、配置標志)。
注意事項
- ?避免過度使用靜態成員:可能導致代碼耦合度高、難以測試。
- ?線程安全問題:靜態成員在多線程環境下需加鎖(如
lock
)。- ?常量的限制:無法在運行時動態賦值(如從配置文件讀取)。
- ?靜態構造函數的性能:避免在靜態構造函數中執行耗時操作。
????????通過合理使用靜態成員和常量,可以顯著提升代碼的模塊化和執行效率,但需謹慎平衡其適用場景!