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

C# readonly 欄位深度解析:編譯期常數 vs 執行期常數與版本控制策略

     編輯:關於C#

readonly 基本語法與規則

public class Constants {
    // 宣告時初始化
    public static readonly double PI = 3.1415926535;
    public static readonly Color White = new Color(255, 255, 255);

    // 建構子初始化 (僅限實例 readonly)
    public readonly Guid InstanceId;
    public Constants() => InstanceId = Guid.NewGuid();
}
  • 只能在宣告處或建構子中賦值。
  • static readonly 屬於類別,在靜態建構子或宣告處初始化。
  • 實例 readonly 在每個實例建構時初始化。

readonly vs const:核心差異對比

特性constreadonly
初始化時機編譯期執行期 (靜態建構子/實例建構子)
允許型別內建值型別 + string任意型別 (含參考型別、陣列、自訂結構)
IL 表現數值內嵌至呼叫端保留欄位參考,執行期讀取
版本控制影響修改值需重新編譯所有消費者組件修改值無需重新編譯消費者組件
屬性參數使用可作為屬性參數不可

版本控制實戰示範

// AssemblyA.dll (Library)
namespace Lib {
    public class Config {
        public static readonly int MaxConnections = 100; // v1.0
        // 升級為 v1.1: public static readonly int MaxConnections = 200;
    }
}

// AssemblyB.exe (Consumer)
using Lib;
class Program {
    static void Main() {
        Console.WriteLine(Config.MaxConnections); // 執行期讀取 AssemblyA 當前值
    }
}

若 MaxConnections 是 const,升級 Library 後 Consumer 必須重新編譯才能取得新值;改用 static readonly,Consumer 直接執行新版 DLL 即可獲得新值,實現二進位相容版本控制。

進階用法:readonly 結構體與陣列

public readonly struct Point3D {
    public readonly double X, Y, Z; // C# 7.2+ readonly 修飾詞可加在欄位
    public Point3D(double x, double y, double z) { X = x; Y = y; Z = z; }
}

public class DataHolder {
    public static readonly int[] Primes = { 2, 3, 5, 7, 11 }; // 陣列參考不可變,但元素可修改!
    // 若需元素也不可變,改用 ImmutableArray 或 readonly struct 陣列
}

常見誤區

  1. 以為 readonly 陣列元素不可變 → 只有陣列參考不可變,元素仍可修改。
  2. 在方法中嘗試修改 readonly 欄位 → 編譯錯誤 CS0191。
  3. 結構體欄位未加 readonly 導致防禦性複製效能損失 → C# 7.2+ 建議加 readonly 修飾結構體欄位。

最佳實務建議

  • 公開常數預設用 static readonly,除非需作為屬性參數或編譯期常數運算。
  • 不可變物件模式:所有欄位 readonly,透過建構子初始化。
  • 搭配 init 存取器 (C# 9) 實現更優雅的不可變物件初始化。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved