news 2026/3/29 20:08:27

深入解析 C# 中 const 与 readonly 的核心区别

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
深入解析 C# 中 const 与 readonly 的核心区别

在 C# 编程中,constreadonly经常被统称为“常量”,但二者在初始化规则、编译/运行时行为、IL 生成方式、版本兼容性、引用类型语义等方面存在本质差异。误用不仅可能引入隐蔽的逻辑错误,还会带来库升级后的版本陷阱


一、初始化位置:编译时强约束 vs 运行时一次性赋值

1️⃣const必须声明即赋值(编译期确定)

  • 必须在声明处赋值
  • 值在编译阶段就已确定
  • 任何位置都不能再次赋值(包括构造函数)
public class ConstantDemo { public const int MaxRetryCount = 3; public const string DefaultTitle = "C#常量解析"; // ❌ 编译错误:声明时未赋值 // public const double Pi; // ❌ 编译错误:不能在构造函数中修改 // public ConstantDemo() // { // MaxRetryCount = 5; // } }

📌结论const是“声明即终值”的编译期常量


2️⃣readonly声明时或构造函数中赋值(运行期确定)

  • 可以在声明处赋值
  • 也可以在实例构造函数 / 静态构造函数中赋值
  • 每个字段只允许赋值一次
public class ReadonlyDemo { // 声明时赋值 public readonly int MinAge = 18; // 构造函数中赋值 public readonly int UserId; public ReadonlyDemo(int userId) { UserId = userId; } // 静态 readonly:在静态构造函数中赋值 public static readonly string Version; static ReadonlyDemo() { Version = "1.0.1"; } }

📌结论readonly是“构造期冻结”的运行时常量。


二、修饰对象范围:字段 + 局部变量 vs 仅字段

const:字段 & 局部变量都支持

public class ConstScopeDemo { public const int GlobalConst = 100; public void LocalConstDemo() { const string LocalMsg = "局部常量"; Console.WriteLine(LocalMsg); } }

readonly只能修饰字段

public class ReadonlyScopeDemo { public readonly int FieldReadonly = 50; public void LocalReadonlyError() { // ❌ 编译错误:readonly 不能修饰局部变量 // readonly int x = 10; } }

三、编译期 vs 运行期:这是最本质的差异 ⭐⭐⭐

1️⃣const值被直接“内联”到 IL 中

public const int ConstValue = 10; public void UseConst() { int a = ConstValue; }

IL 行为本质

ldc.i4.s 10 // 直接压栈常量 10

⚠️重大隐患(版本陷阱)

  • 修改类库中的const
  • 引用方未重新编译
  • 引用方仍然使用旧值 ❌

2️⃣readonly始终通过字段访问(运行期绑定)

public readonly int ReadonlyValue; public ReadonlyDemo() { ReadonlyValue = 20; } public void UseReadonly() { int b = ReadonlyValue; }

IL 行为本质

ldfld int32 ReadonlyValue

✅ 修改值后,只需重新编译类库即可,调用方无需重新编译


四、静态语义:隐式静态 vs 显式静态

const天然 static,且禁止显式声明

public class ConstStaticDemo { public const int ConstStatic = 10; // ❌ 编译错误 // public static const int Invalid = 20; }

调用方式:

int x = ConstStaticDemo.ConstStatic;

readonly:默认实例级,静态需显式声明

public class ReadonlyStaticDemo { public readonly int InstanceReadonly = 100; public static readonly int StaticReadonly = 200; }

五、引用类型语义:值不可变 vs 引用不可变

const:仅支持string/null

public class ConstReferenceDemo { public const string ConstString = "Hello"; public const object ConstNull = null; // ❌ 编译错误 // public const List<int> ConstList = new List<int>(); }

原因:

  • const需要编译期确定值
  • string外,引用对象无法编译期确定

readonly:支持任意引用类型(但仅锁引用)

public class ReadonlyReferenceDemo { public readonly List<int> Numbers = new() { 1, 2, 3 }; public void Modify() { Numbers.Add(4); // ✅ 合法 // ❌ 编译错误:不能重新赋值 // Numbers = new List<int>(); } }

⚠️readonly≠ 不可变对象

  • 锁的是引用地址
  • 不是对象内容

六、完整对比速查表

维度constreadonly
初始化时机编译期运行期
赋值位置仅声明处声明 / 构造函数
修饰对象字段 + 局部变量仅字段
静态特性默认 static默认实例级
IL 行为内联常量字段访问
引用类型string / null任意引用类型
版本安全❌ 易出问题✅ 安全

七、工程化使用建议(非常重要)

✅ 优先使用const的场景

  • 数学常量(PIE
  • 永不变化的协议值、枚举值
  • 不会被类库外部依赖引用的内部常量
public const int MaxDays = 7;

✅ 推荐使用readonly的场景(真实项目更常见)

  • 类库对外暴露的“常量”
  • 配置读取、构造参数注入
  • 引用类型常量(集合、策略对象等)
public static readonly string ConnectionString; static DbConfig() { ConnectionString = LoadFromConfig(); }

八、一句话记忆法(面试 & 实战)

const是“编译期写死的字面量”
readonly是“构造期冻结的字段”


结语

constreadonly的差异,本质并不在“能不能改”,而在于:

  • 值是在什么时候决定的?(编译期 vs 运行期)
  • 是否参与 IL 内联?
  • 是否影响程序集版本兼容?

在真实工程中:

🔥99% 对外暴露的“常量”,都应该使用readonly而不是const

理解这一点,你就已经超过了大多数只停留在语法层面的 C# 开发者。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/28 23:03:36

Skyvern终极指南:如何用AI自动化网页操作实现效率翻倍

在现代工作环境中&#xff0c;重复性的网页操作占据了大量宝贵时间。无论是数据抓取、表单填写还是文件下载&#xff0c;这些看似简单的任务往往成为效率的瓶颈。Skyvern作为一款革命性的AI自动化工具&#xff0c;正改变着这一现状。通过智能解析自然语言指令&#xff0c;Skyve…

作者头像 李华
网站建设 2026/3/20 9:53:28

Qwen-Image-Edit-2509:重塑图像编辑的智能边界

Qwen-Image-Edit-2509&#xff1a;重塑图像编辑的智能边界 【免费下载链接】Qwen-Image-Edit-2509 项目地址: https://ai.gitcode.com/hf_mirrors/Qwen/Qwen-Image-Edit-2509 当创意与技术的边界不断被突破&#xff0c;我们是否曾思考&#xff1a;图像编辑的未来究竟在…

作者头像 李华
网站建设 2026/3/27 8:54:15

DrissionPage终极指南:5步实现文件下载自动化与智能分类

DrissionPage终极指南&#xff1a;5步实现文件下载自动化与智能分类 【免费下载链接】DrissionPage Python based web automation tool. Powerful and elegant. 项目地址: https://gitcode.com/gh_mirrors/dr/DrissionPage 在当今数据驱动的时代&#xff0c;高效的文件管…

作者头像 李华
网站建设 2026/3/27 2:31:40

揭秘AI黑箱:用PyTorch显著性图技术提升模型可解释性

揭秘AI黑箱&#xff1a;用PyTorch显著性图技术提升模型可解释性 【免费下载链接】pytorch-deep-learning Materials for the Learn PyTorch for Deep Learning: Zero to Mastery course. 项目地址: https://gitcode.com/GitHub_Trending/py/pytorch-deep-learning 在当今…

作者头像 李华
网站建设 2026/3/25 7:56:37

Winhance:重新定义Windows系统优化体验的智能工具

在数字化时代&#xff0c;Windows系统作为全球使用最广泛的操作系统&#xff0c;其性能表现直接影响着亿万用户的日常工作和娱乐体验。传统系统优化方法往往需要用户具备专业技术知识&#xff0c;操作复杂且风险较高。现在&#xff0c;Winhance的出现彻底改变了这一局面&#x…

作者头像 李华
网站建设 2026/3/26 0:29:23

Vita3K模拟器完整使用指南:从安装到精通

Vita3K模拟器完整使用指南&#xff1a;从安装到精通 【免费下载链接】Vita3K Experimental PlayStation Vita emulator 项目地址: https://gitcode.com/gh_mirrors/vi/Vita3K 想要在PC上体验PSVita游戏的魅力吗&#xff1f;Vita3K模拟器为你打开了通往掌机游戏世界的大门…

作者头像 李华