首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >C# 9的init魔法:比readonly更优雅的不可变性设计

C# 9的init魔法:比readonly更优雅的不可变性设计

作者头像
郑子铭
发布2025-08-14 15:06:03
发布2025-08-14 15:06:03
19000
代码可运行
举报
运行总次数:0
代码可运行

C#长久以来通过readonly字段支持不可变对象,但C# 9引入的init关键字带来了更灵活的不可变性控制方案。这个看似简单的语法糖,能在保持代码简洁性的同时,为你的对象构建过程加上编译时安全锁。

🔍 init是什么? 表面看init类似属性setter,但它的核心区别在于:仅允许在对象初始化阶段赋值,构造完成后立即变为只读状态。

传统可变属性:

代码语言:javascript
代码运行次数:0
运行
复制
public class Person
{
    public string Name { get; set; }  // 随时可修改
    public int Age { get; set; }
}

使用init的不可变属性:

代码语言:javascript
代码运行次数:0
运行
复制
public class Person
{
    public string Name { get; init; }  // 仅初始化时可设值
    public int Age { get; init; }
}

🚀 init的三大优势

  1. 1. 强制不可变模式 防止对象构造后意外修改,杜绝副作用。以下代码将引发编译错误:
代码语言:javascript
代码运行次数:0
运行
复制
var person = new Person { Name = "Alice" };
person.Name = "Bob";  // ❌ CS0272 不可修改
  1. 2. 保持对象初始化器的优雅语法
代码语言:javascript
代码运行次数:0
运行
复制
// 初始化阶段仍可使用流畅语法
var product = new ProductDTO { 
    Id = , 
    Name = "Surface Pro" 
};
  1. 3. 完美适配DTO和值类型 特别适合API响应模型等场景:
代码语言:javascript
代码运行次数:0
运行
复制
public class ApiResponse<T>
{
    public T Data { get; init; }
    public DateTime Timestamp { get; init; } = DateTime.UtcNow;
}

与readonly的终极对比

特性

readonly字段

init属性

赋值时机

仅构造函数内

对象初始化阶段

是否支持初始化器语法

❌ 不支持

✅ 完美支持

适用场景

完全不可变的核心字段

需初始化灵活性的模型

🔥 与record的黄金组合 C# 9的record类型本身具有值语义不可变性,配合init实现双重保护:

代码语言:javascript
代码运行次数:0
运行
复制
public record FinancialTransaction(
    decimal Amount,
    string Currency)
{
    public Guid TransactionId { get; init; } = Guid.NewGuid();
}

// 使用示例
var tx = new FinancialTransaction(99.99m, "USD") { 
    TransactionId = Guid.Parse("...") 
};

💡 设计决策指南

  • • 需要完全不可变?用readonly字段+构造函数
  • • 需要初始化灵活性?用init属性
  • • 需要值语义比较?用record+init

🎯 最佳实践场景

  1. 1. API响应模型 - 防止序列化后篡改
  2. 2. 配置对象 - 确保运行时配置不可变
  3. 3. 领域值对象 - 配合DDD模式使用
  4. 4. 并发共享数据 - 天然线程安全

init关键字虽小,却是C#不可变性设计的重要拼图。它巧妙地填补了readonly严格限制与setter完全自由之间的空白,让开发者能以最小成本获得最大安全性。下次设计模型时,不妨让init成为你的首选武器。

代码语言:javascript
代码运行次数:0
运行
复制
点击下方卡片关注DotNet NB
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-08-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DotNet NB 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档