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

Effective C# 原則 2:常數優先用 readonly 而非 const(下)

     編輯:關於C語言

IL 層面差異:編譯時常數 vs 執行時常數

const:編譯器將值直接內嵌至呼叫端 IL(ldc.i4),如同硬編碼。
readonly:執行時讀取欄位值(ldsfld),支援任意型別與建構函式初始化。

版本演進陷阱

// 組件 A (Library.dll)
public class Constants
{
    public const int MaxRetries = 3;        // 編譯時常數
    public static readonly int Timeout = 5000; // 執行時常數
}

// 組件 B (App.exe) 參考 A
void Foo() 
{
    int a = Constants.MaxRetries;  // IL 內嵌為 ldc.i4.3
    int b = Constants.Timeout;     // IL 為 ldsfld 讀取欄位
}

若 A 更新 MaxRetries = 5 但 B 未重新編譯,B 仍使用舊值 3。
readonly 則會在執行時讀取新值,無需重新編譯呼叫端。

序列化版本控制實例

// 版本標識使用 const(永不變更)
private const int VERSION_1_0 = 0x0100;
private const int VERSION_2_0 = 0x0200;

// 當前版本使用 readonly(發布時更新)
private static readonly int CurrentVersion = VERSION_2_0;

// 反序列化時比對版本
protected MyType(SerializationInfo info, StreamingContext ctx)
{
    int stored = info.GetInt32("VERSION");
    switch (stored)
    {
        case VERSION_2_0: ReadV2(info, ctx); break;
        case VERSION_1_0: ReadV1(info, ctx); break;
    }
}

// 序列化寫入當前版本
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext ctx)
{
    info.AddValue("VERSION", CurrentVersion); // 執行時讀取最新值
}

效能權衡

const 存取略快(直接常數),但差異極微(納秒級)。除非極度效能敏感且值永不變更,否則優先選擇 readonly 的彈性。

決策速查表

情境建議
屬性參數const(編譯時需常數)
列舉底層值const(隱含)
永不變更的基本型別常數const 可接受
可能隨版本變更的值readonly
非基本型別readonly(const 不支援)
需在建構函式初始化readonly
執行個體層級常數readonly(const 隱含 static)

總結

預設使用 readonly,只有明確理由時才用 const。這能避免版本演進時的靜默錯誤,支援更豐富的型別與初始化邏輯。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved