C# with表达式:优雅地创建对象副本

目录
with是C# 9.0引入的一个非常实用的特性,它让我们可以在保留原对象大部分属性的情况下,只修改少量属性并创建一个新对象。它尤其适合与record、不可变对象(Immutable Object)以及函数式编程风格结合使用。
为什么需要with?
假设为门有一个用户类:
|
|
现有有一个用户:
|
|
如果我们希望创建一个年龄为21岁的新用户:
|
|
代码没有问题,但存在一个明显的问题:我们只是想修改一个属性,却需要重新填写所有属性。可以预想到,如果属性很多,代码会变得非常繁琐。这时with就非常有用了。
with的基本用法
|
|
执行之后,原来的user不会发生变化。这就是with的方便之处,基于已有对象创建一个新的对象,同时只修改指定成员。注意:with并不是修改原对象,而是创建了一个新对象。
我们可以验证:
|
|
说明两个变量指向的是不同对象。
with是浅拷贝
with并不意味着递归复制整个对象。例如:
|
|
创建:
|
|
然后:
|
|
此时:
|
|
说明两个User是不同对象,但它们引用的是同一个Address。所以,with默认是浅复制(Shallow Copy),而不是深复制(Deep Copy)。
总结
C#的with表达式可以基于已有对象创建新的对象,而不是直接修改已有对象。最典型的组合是:record + with。二者结合后,可以非常自然地床见不可变对象:
|
|
需要记住三点:
with会创建新对象,而不是修改原对象with默认是浅复制,不是深复制with特别适合record和不可变状态
相关内容
- Polly使用指南:.NET应用程序可靠性设计
- WPF UI:让WPF应用具有Fluent Design风格
- .NET设计规范 约定、惯用法与模式 第2版 (Krzysztof Cwalina / Brad Abrams)
- CLR via C# 第4版 (Jeffrey Richter)
- Microsoft.Extensions.Hosting使用指南:构建现代 .NET 应用的通用宿主架构
- WPF编程宝典 第4版 (Matthew MacDonald)
- C# LINQ学习之旅:从集合操作到声明式编程
- Design Patterns in C# and .NET (Dmitri Nesteruk)
- Modbus协议从入门到实战
- 从SerialPort到工业级通信框架设计
- shadowsocks-windows源码剖析:一个C#网络代理客户端是如何工作的?
- 深入System.Net.NetworkInformation获取系统网络信息
- NETworkManager源码剖析:一个网络管理工具的实现细节
- DotNetty源码剖析:高性能网络框架的秘密
- C#高效编程 改进C#代码的50个行之有效的办法 第2版 (Bill Wagner)
- Downloader源码剖析:一个下载器的实现原理
- C#中的nameof运算符
请作者喝杯咖啡!
支付宝
微信