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

C# const 與 readonly 差異完整解析:編譯期常數 vs 運行期常數

     編輯:關於C語言

核心差異速查表

特性constreadonly
初始化時機編譯期 (必須為常數運算式)運行期 (建構函式或宣告處)
可用變數初始化否是
靜態性隱含 static預設為實例成員,需顯式 static readonly
型別限制僅限值型別 + string + null任意型別 (含參考型別、結構、陣列)
不同實例不同值不可 (全程式共享)可 (每個實例可不同)
IL 標記literalinitonly
跨組件版本風險高 (值內嵌入呼叫端 IL)低 (運行期讀取欄位)

代碼示範

const:編譯期常數

public const double PI = 3.14159;           // OK
public const int MaxSize = 100 * 1024;      // OK: 常數運算式
// public const int Value = GetValue();     // 編譯錯誤: 非常數運算式
// public const MyClass Obj = new MyClass(); // 錯誤: 僅限 string/null

readonly:運行期常數

public readonly int InstanceId;             // 實例唯讀
public static readonly string AppName;      // 靜態唯讀

public MyClass()
{
    InstanceId = Interlocked.Increment(ref _counter); // 運行期賦值
    // InstanceId = 999; // 建構函式外賦值 → 編譯錯誤
}

static MyClass()
{
    AppName = "MyApp " + DateTime.Now.Year; // 靜態建構函式賦值
}

參考型別 readonly 陷阱

public static readonly List Items = new List();

// 合法:修改集合內容
Items.Add("A"); 
Items[0] = "B";

// 非法:重新指派參考
// Items = new List(); // 編譯錯誤

// 結構體 readonly 則完全不可變
public readonly struct Point { public int X, Y; }
public static readonly Point Origin = new Point(); 
// Origin.X = 1; // 錯誤:readonly 結構體成員不可變

static readonly 進階用法

// 運行期初始化,支援複雜邏輯
private static readonly string DataPath = 
    Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data");

private static readonly Lazy Resource = 
    new Lazy(() => new ExpensiveResource(), true); // 執行緒安全延遲初始化

版本相容性陷阱

組件 A 定義:

// Assembly A v1.0
public const int MaxConnections = 100;
public readonly int DefaultTimeout = 30;

組件 B 參考 A:

// Assembly B
Console.WriteLine(A.MaxConnections);    // IL 內嵌為 100
Console.WriteLine(A.DefaultTimeout);    // IL 為 ldsfld 讀取欄位

升級 A 為 v2.0:

// Assembly A v2.0
public const int MaxConnections = 200;
public readonly int DefaultTimeout = 60;

不重新編譯 B 直接替換 A.dll:

  • MaxConnections:B 仍輸出 100 (值已燒錄進 B 的 IL)
  • DefaultTimeout:B 輸出 60 (運行期讀取新值)

結論:公開常數謹慎使用 const,跨組件共享配置值請用 static readonly。

最佳實踐建議

  • 真正不變的基礎常數 (π、單位換算、固定演算法參數) → const
  • 配置值、資源路徑、靜態快取、依賴注入 Token → static readonly
  • 實例級不可變資料 (ID、建構時注入的設定) → readonly
  • 不可變物件模式:結構體加 readonly、類別欄位全 readonly + 唯讀屬性
  • 避免:public const 用於可能變更的業務配置
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved