【C#】C# 中的 `init`、`readonly` 和 `const` 有什么区别?

⚙️ C# 中的 initreadonlyconst 有什么区别?

在 C# 编程中,我们经常需要定义 不可变(immutable) 的数据。那么该用 constreadonly,还是 init 呢?这三者虽然都可用于定义不可变成员,但它们的应用场景和语法限制却大不相同。本文将通过对比和示例,帮助你理清它们的区别与用法。


📌 1. 简要对比表

特性 const readonly init
赋值时机 定义时 构造函数或定义时 初始化时(对象构造期间)
是否编译期常量 ✅ 是 ❌ 不是 ❌ 不是
可用于字段 ✅(属性)
可用于属性 ✅(支持 get-only) ✅(支持 set-only-once)
赋值位置 定义时 构造函数、字段初始化 对象初始化表达式 {}
常用于 全局常量、数学值 构造后不变的实例字段 构造后不变但支持对象初始化的属性

🧱 2. const ------ 编译期常量

csharp 复制代码
public class Constants
{
    public const double Pi = 3.14159;
}

✅ 特点:

  • 必须在定义时赋值
  • 编译为常量值,直接嵌入调用代码中
  • 只能修饰 基本类型string 等编译期常量

⚠️ 注意:

  • 修改 const 值需 重新编译所有引用它的程序集,否则可能仍然使用旧值!

🧱 3. readonly ------ 运行期常量(构造后不可变)

csharp 复制代码
public class Config
{
    public readonly string Version;

    public Config(string version)
    {
        Version = version;
    }
}

✅ 特点:

  • 可以在定义时或构造函数中赋值
  • 适合依赖运行期值(如时间戳、GUID、配置文件)
csharp 复制代码
public readonly DateTime StartTime = DateTime.Now;

⚠️ 注意:

  • readonly 不能在构造函数外被修改
  • 可用于字段,常配合 private 修饰

🧱 4. init ------ 初始化器赋值(C# 9 引入)

csharp 复制代码
public class Person
{
    public string Name { get; init; }
    public int Age { get; init; }
}

✅ 特点:

  • 支持对象初始化表达式语法 {} 中赋值
  • 一旦对象构造完成,属性就不可更改
csharp 复制代码
var p = new Person { Name = "Alice", Age = 30 };
// p.Age = 31; // ❌ 编译错误

👍 优势:

  • 与面向对象封装天然适配
  • 保留不可变性同时支持初始化灵活性

🚩 5. 使用建议总结

使用场景 推荐关键词 理由
编译期不会变化的值(如 Pi) const 编译时已确定,性能更优
运行期动态初始化的字段 readonly 构造函数中灵活赋值,构造后不可变
想使用初始化表达式设定属性值 init 可读性强,避免创建多个构造函数
想实现不可变对象(immutable) init + get 提供只读接口,同时允许构造期间初始化

✅ 总结

关键词 可变性 赋值时机 使用场景
const 永远不可变 定义时 编译期常量
readonly 构造后不可变 构造函数或定义时 运行期常量,依赖构造动态赋值
init 构造后不可变 对象初始化表达式期间 封装属性,构造时赋值灵活

选择合适的不可变策略,可以帮助你写出更安全、清晰、易维护的代码!


📬 你更常用哪种不可变成员定义方式?欢迎评论区分享你的使用经验!

如果你觉得这篇文章有帮助,别忘了点赞、收藏和关注我~ 🚀

相关推荐
Cyrus_柯2 小时前
C++(面向对象编程——关键字)
开发语言·c++·算法·面向对象
大龄Python青年2 小时前
C语言 函数怎样通过数组来返回多个值
c语言·开发语言
LQYYDSY2 小时前
【C语言极简自学笔记】重讲运算符
c语言·开发语言·笔记
2013编程爱好者2 小时前
C++二分查找
开发语言·c++·算法·二分查找
电商数据girl2 小时前
【经验分享】浅谈京东商品SKU接口的技术实现原理
java·开发语言·前端·数据库·经验分享·eclipse·json
棉晗榜2 小时前
C# .net core添加单元测试项目,依赖注入接口测试
单元测试·c#·.netcore
十五年专注C++开发3 小时前
QSimpleUpdater:解锁 Qt 应用自动更新的全新姿势
开发语言·c++·qt
小猫咪怎么会有坏心思呢3 小时前
华为OD机考-货币单位换算-字符串(JAVA 2025B卷)
java·开发语言·华为od
想不到耶3 小时前
Vue3轮播图组件,当前轮播区域有当前图和左右两边图,两边图各显示一半,支持点击跳转和手动滑动切换
开发语言·前端·javascript
虾球xz3 小时前
CppCon 2016 学习:BUILDING A MODERN C++ FORGE FOR COMPUTE AND GRAPHICS
开发语言·c++·学习