const 欄位宣告標準語法
[attributes] [const-modifiers] const type constant-declarators;
const-modifiers: new / public / protected / internal / private
// 隱含 static,不可顯式寫 static
基本宣告範例
public class Physics {
public const double SpeedOfLight = 299792458; // m/s
public const double GravitationalConstant = 6.67430e-11; // m^3 kg^-1 s^-2
public const string TheoryName = "General Relativity";
}
// 合併宣告同型別多個常數
public class AppConfig {
public const int MaxConnections = 100, DefaultPort = 8080, BufferSize = 4096;
public const string AppName = "MyApp", Version = "1.0.0";
}
const 核心特性與限制
| 特性 | 說明 | 影響 |
| 編譯期常數 | 值在編譯時確定 | 不可為執行期才能決定的值 (如 DateTime.Now、Guid.NewGuid()) |
| 隱含 static | 屬於類別,非實例 | 透過 類別名.常數名 存取,不可 this.常數名 |
| 值內嵌 | 編譯器將常數值直接寫入呼叫端 IL | 修改常數值需重新編譯所有引用組件,否則舊值殘留 |
| 型別限制 | sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool, string, enum, null | 不可為自訂類別/結構體/陣列 (除非 null) |
| 可用於屬性參數 | [MyAttribute(Math.PI)] | readonly 欄位不可用於屬性參數 |
const vs static readonly 深度對比
public class Constants {
// const:編譯期內嵌,版本控制不友善
public const int Version = 1;
// static readonly:執行期讀取,版本控制友善
public static readonly int BuildNumber = GetBuildNumber(); // 可執行運算式
public static readonly string BuildTime = DateTime.UtcNow.ToString("O");
public static readonly Guid AssemblyId = Guid.NewGuid();
public static readonly Color ThemeColor = Color.FromArgb(0xFF, 0x33, 0x66, 0x99);
}
版本控制實戰情境
- Library v1.0:
public const int MaxUsers = 100;
- Consumer 編譯參考 Library v1.0 → IL 內嵌
100。
- Library v1.1:
public const int MaxUsers = 200; (未重新編譯 Consumer)。
- Consumer 執行 → 仍讀到
100 (IL 已內嵌)。
- 改用
static readonly → Consumer 執行新版 DLL 直接讀到 200。
常見編譯錯誤
| 錯誤碼 | 原因 | 修正 |
| CS0133 | 常數值無法在編譯期計算 | 改用 static readonly 或 constexpr 運算式 |
| CS0134 | 常數型別不支援 (如自訂結構) | 改用 static readonly |
| CS0270 | 陣列大小不可為常數 (C# 不支援常數陣列大小) | 改用 static readonly 陣列 |
| CS0436 | 類型衝突 (同名常數來自不同組件) | 使用完整命名空間限定 |
最佳實務建議
- 真正的普世常數 (PI、物理常數、協定版本號) →
const。
- 組件內部設定、可執行運算式初始化、參考型別、版本控制需求 →
static readonly。
- 公開 API 常數變更視為中斷性變更,遵循 SemVer 主版本號遞增。