news 2026/7/3 5:38:43

深入解析 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/7/1 11:51:34

Chrome Driver与Selenium集成实战案例解析

从零构建浏览器自动化&#xff1a;ChromeDriver Selenium 实战全解析 你有没有遇到过这样的场景&#xff1f; 一个简单的 UI 回归测试&#xff0c;手动点击十几步才能验证结果&#xff1b;或者 CI/CD 流水线跑着跑着突然卡住&#xff0c;只因为没人去点“确认”弹窗。更别提那…

作者头像 李华
网站建设 2026/7/1 22:44:07

NVIDIA Isaac ROS Visual SLAM:机器人定位的终极解决方案

NVIDIA Isaac ROS Visual SLAM&#xff1a;机器人定位的终极解决方案 【免费下载链接】isaac_ros_visual_slam Visual odometry package based on hardware-accelerated NVIDIA Elbrus library with world class quality and performance. 项目地址: https://gitcode.com/gh_…

作者头像 李华
网站建设 2026/7/1 11:51:33

终极指南:3大核心模块快速搭建Python量化交易系统

想要摆脱手动交易的繁琐&#xff0c;迈入自动化交易的世界&#xff1f;vnpy作为基于Python的开源量化交易平台开发框架&#xff0c;为你提供了完整的量化交易解决方案。无论你是股票、期货还是其他资产交易者&#xff0c;都能通过这个强大的Python量化工具快速构建自己的自动交…

作者头像 李华
网站建设 2026/7/1 11:51:31

智能育儿新范式:用Parlant构建下一代AI教育助手

在数字化育儿时代&#xff0c;家长们面临着一个两难选择&#xff1a;既希望孩子享受科技带来的学习乐趣&#xff0c;又担心内容安全和教育质量。传统的教育APP往往要么过于娱乐化&#xff0c;要么缺乏个性化引导。Parlant作为专为面向客户场景设计的LLM智能体框架&#xff0c;通…

作者头像 李华
网站建设 2026/7/1 21:08:40

深度解析AI安全边界:system-reminder隔离机制如何重塑智能系统防护

深度解析AI安全边界&#xff1a;system-reminder隔离机制如何重塑智能系统防护 【免费下载链接】analysis_claude_code 本仓库包含对 Claude Code v1.0.33 进行逆向工程的完整研究和分析资料。包括对混淆源代码的深度技术分析、系统架构文档&#xff0c;以及重构 Claude Code a…

作者头像 李华