【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 构造后不可变 对象初始化表达式期间 封装属性,构造时赋值灵活

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


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

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

相关推荐
wjs202415 小时前
DOM CDATA
开发语言
Tingjct15 小时前
【初阶数据结构-二叉树】
c语言·开发语言·数据结构·算法
猷咪16 小时前
C++基础
开发语言·c++
IT·小灰灰16 小时前
30行PHP,利用硅基流动API,网页客服瞬间上线
开发语言·人工智能·aigc·php
快点好好学习吧16 小时前
phpize 依赖 php-config 获取 PHP 信息的庖丁解牛
android·开发语言·php
秦老师Q16 小时前
php入门教程(超详细,一篇就够了!!!)
开发语言·mysql·php·db
烟锁池塘柳016 小时前
解决Google Scholar “We‘re sorry... but your computer or network may be sending automated queries.”的问题
开发语言
是誰萆微了承諾16 小时前
php 对接deepseek
android·开发语言·php
2601_9498683616 小时前
Flutter for OpenHarmony 电子合同签署App实战 - 已签合同实现
java·开发语言·flutter
星火开发设计16 小时前
类型别名 typedef:让复杂类型更简洁
开发语言·c++·学习·算法·函数·知识