首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# const 與 static readonly 差異深度解析:編譯期常數 vs 執行期唯讀欄位

     編輯:關於C語言

核心差異對照表

維度conststatic readonly
初始化時機編譯期執行期(型別建構器/.cctor)
值儲存位置直接內嵌至呼叫端 IL儲存在型別靜態欄位
型別限制僅基本型別、string、null、enum任意型別(含陣列、物件、結構體)
修飾詞隱含 static,不可加 static需顯式 static
版本相容性修改值需重新編譯所有呼叫端僅更新定義端組件即可
屬於常數唯讀靜態欄位

實戰驗證:跨組件版本更新

類別庫


// Example02Lib.dll v1
public class Config {
    public const string Version = "1.0.0";
    public static readonly string BuildDate = "2024-01-01";
}

呼叫端


// Example02.exe 參考 v1
Console.WriteLine($"Const: {Config.Version}");       // IL 內嵌 "1.0.0"
Console.WriteLine($"Readonly: {Config.BuildDate}"); // 運行時讀取欄位

更新類別庫不重新編譯呼叫端


// Example02Lib.dll v2 (僅重新建置庫)
public class Config {
    public const string Version = "2.0.0";          // 修改常數值
    public static readonly string BuildDate = "2024-06-15"; // 修改唯讀值
}

執行結果


Const: 1.0.0        // 呼叫端 IL 仍內嵌舊值
Readonly: 2024-06-15 // 讀取更新後的欄位值

IL 層面解析


// const 呼叫端 IL
ldstr "1.0.0"        // 直接載入字串常數

// static readonly 呼叫端 IL
ldsfld string Config::BuildDate // 載入靜態欄位值

選擇指南

情境建議理由
真正不變的常數(PI、物理常數、協定版本)const零開銷、語意明確
可能更新的設定值(連線字串、路徑、業務參數)static readonly支援熱更新、型別無限制
參考型別/陣列/集合static readonlyconst 僅支援 string/null
需在屬性/Attribute 使用constAttribute 參數需編譯期常數
Switch case 標籤constcase 標籤需常數

進階:readonly 實例欄位


class Service {
    private readonly HttpClient _client; // 實例唯讀
    public Service() => _client = new HttpClient(); // 僅能在建構函式初始化
    // 或 C# 6+ 初始化器
    private readonly string _name = "Default";
}
  • readonly 實例欄位:建構函式結束前可多次指派,之後不可變
  • 適用於不可變物件模式、依賴注入欄位

常見錯誤

  1. const 用於連線字串 → 修改需重新部署所有消費者
  2. static readonly 陣列/集合 → 欄位不可變,但元素可變(需用 ImmutableArray 或 ReadOnlyCollection)
  3. 在 static readonly 初始化器中呼叫虛擬方法 → 型別建構器執行順序風險
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved