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

C# 定義常數的兩種方式:const vs readonly 深度比較

     編輯:關於C#

語法與基本差異

特性const (編譯期常數)readonly (執行期常數)
宣告public const int Max = 100;public readonly int Max = 100;
初始化時機**宣告時必須指定值**宣告時或**建構函式中**指定
隱含修飾詞隱含 static預設為實例欄位 (可加 static)
型別限制僅限**值型別** + string + null (不可 new)**任意型別** (含參考型別、陣列、自訂結構)
記憶體不佔用實例/靜態儲存空間 (IL 內嵌常值)佔用欄位儲存空間
存取方式ClassName.ConstName實例欄位:instance.Field;靜態:ClassName.Field
IL 行為編譯時**將常值直接內嵌**至呼叫端 IL執行時**讀取欄位值**

關鍵差異:版本相容性陷阱

const 為編譯期內嵌:若類庫定義 public const int V = 1;,消費者編譯後 IL 變為 ldc.i4.1。類庫更新為 V = 2,**消費者不重新編譯仍見 1**,導致行為不一致。

readonly 為執行期讀取:消費者 IL 為 ldsfld V,類庫更新後直接讀取新值,**無需重新編譯**。


// 類庫 Library.dll v1
public class Config { public const int Timeout = 30; }

// 消費者 App.exe 編譯後 IL 相當於
int t = 30; // 常值內嵌

// 類庫 Library.dll v2 (未重新編譯 App.exe)
public class Config { public const int Timeout = 60; }
// App.exe 執行時仍使用 30 → **潛在 Bug**

// 若改用 readonly
public class Config { public static readonly int Timeout = 30; }
// App.exe IL: ldsfld int32 Config::Timeout
// 更新 Library.dll 後 App.exe 自動讀取 60 → **安全**

適用場景建議

場景推薦理由
真正不變的通用常數 (π, 物理常數, 固定枚舉值)const效能最佳、語意明確
設定值、可調整參數、跨組件共用常數static readonly版本相容、支援參考型別
每個實例不同的不可變資料 (如 Entity Id)readonly (實例欄位)建構函式指定、語意明確
需在建構函式中根據參數計算readonlyconst 不支援

現代 C# 新選擇:init-only 屬性 / record


// C# 9+ init-only property
public class Config 
{ 
    public int Timeout { get; init; } = 30; 
}

// C# 9+ record (不可變資料型別)
public record Config(int Timeout = 30, string Server = "localhost");

提供更豐富的不可變語意、with 運算式複製修改、值相等比較,推薦新專案優先使用。

總結

  • const:編譯期常值、隱含 static、型別受限、**版本脆弱**。
  • readonly:執行期欄位、可實例/靜態、型別不限、**版本彈性**。
  • 原則:**預設用 readonly (或 init/record)**,極少數真正永不變更的原始常數才用 const。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved