浅拷贝用MemberwiseClone()仅复制第一层引用,新旧对象共享引用类型子对象;深拷贝推荐System.Text.Json序列化反序列化,安全高效;Newtonsoft.Json更灵活但需引入第三方包;禁用BinaryFormatter。
MemberwiseClone(),但只复制第一层引用在 C# 中,MemberwiseClone() 是最直接的浅拷贝方式,它会创建新对象,并把原对象所有字段值(包括引用)逐字节复制过去。对值类型字段是真正复制,对引用类型字段只是复制“引用地址”,所以新旧对象仍共享同一堆内存中的子对象。
常见错误现象:修改拷贝后对象里的 List 或自定义类实例,原对象也跟着变——这就是浅拷贝的典型副作用。
使用场景有限:仅适用于字段全是值类型、或你明确知道引用字段不需要独立副本的情况(
比如只读缓存对象)。
class,且不能是 sealed 以外的限制(但 MemberwiseClone() 本身是 protected,需在类内部调用)System.Text.Json 序列化反序列化对大多数 POCO 类型,用 System.Text.Json 是目前最轻量、安全、无需额外依赖的深拷贝方案。它把对象转成 JSON 字符串再解析回来,天然切断所有引用关系。
示例:
var original = new Person { Name = "Alice", Address = new Address { City = "Beijing" } };
var clone = JsonSerializer.Deserialize(
JsonSerializer.Serialize(original)); 注意点:
System.Text.Json 默认需要)DateTimeOffset 等部分类型默认序列化(需配置 JsonSerializerOptions)[JsonIgnore] 或 [XmlIgnore] 属性,但不会跳过 private 字段(默认行为)BinaryFormatter 好,且无反序列化远程代码执行风险Newtonsoft.Json
当你的类有 private set、readonly 字段,或继承结构复杂(如抽象基类 + 多个派生类),System.Text.Json 可能无法还原原始字段状态,这时 Newtonsoft.Json 更灵活。
它支持 JsonPropertyAttribute 控制序列化粒度,也能通过 PreserveReferencesHandling.Objects 处理循环引用(虽然深拷贝一般不希望保留引用)。
关键配置示例:
var settings = new JsonSerializerSettings
{
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
var clone = JsonConvert.DeserializeObject(
JsonConvert.SerializeObject(original, settings), settings); 缺点也很明显:
Newtonsoft.Json)System.Text.Json
ReferenceLoopHandling,遇到循环引用直接抛 JsonSerializationException
BinaryFormatter 做深拷贝BinaryFormatter 曾是 .NET Framework 时代常用的深拷贝手段,但它在 .NET 5+ 已被标记为 不安全且废弃,官方明确不建议用于任何新代码。
原因很实在:
[Serializable],且字段不能含不可序列化的资源(如文件句柄、数据库连接)如果你在老项目里看到 BinaryFormatter.Deserialize() 做拷贝,优先替换为 System.Text.Json 方案,哪怕要补几个 [JsonInclude] 或调整构造函数。
真正难的不是选哪种方式,而是判断“这个对象到底需不需要深拷贝”——比如一个只读的 DTO 传参,根本不需要拷贝;而一个正在被多线程修改的配置对象,浅拷贝可能引发竞态。动手前先想清楚数据生命周期和所有权。
# js
# json
# 字节
# c#
# .net
# String
# 构造函数
# 字符串
# 循环
# 继承
# 堆
# class
# 值类型
# 引用类型
# private
# protected
# 线程
# 多线程
# 对象
# 数据库
# 序列化
# 不需要
# 不支持
# 第三方
# 第一层
# 更灵活
# 几个
# 也不
# 多个
# 句柄
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
网络优化76771 】
【
技术知识130152 】
【
IDC云计算60162 】
【
营销推广131313 】
【
AI优化88182 】
【
百度推广37138 】
【
网站推荐60173 】
【
精选阅读31334 】
相关推荐:
Windows10系统服务优化指南_Win10禁用不必要服务提升性能
Python代码测试策略_质量保障解析【教程】
PythonPandas数据分析教程_数据清洗与处理技巧
VSC怎样在VSC中调试PHPAPI_接口调试技巧【详解】
如何使用Golang实现路由分组管理_Golang路由分组与权限控制方法
如何用正则与预处理结合精准拦截拼接式垃圾域名
海外搜索引擎推广效果怎么样,怎么分析效果!
c# 在高并发下使用反射发射(Reflection.Emit)的性能
Win11怎么设置默认终端应用_Windows11开发者选项终端
c++怎么编写动态链接库dll_c++ __declspec(dllexport)导出与调用【方法】
Win11怎样安装微信开发者工具_Win11安装开发者工具教程【步骤】
如何在Golang中写入JSON文件_保存结构体数据到文件
如何在Golang中使用time处理时间_Golang time时间解析与格式化方法
如何用::实现单例模式_php静态方法与作用域操作符应用【技巧】
英国搜索:多数英国人认为语言搜索是未来搜索
Win11怎样彻底卸载自带应用_Win11彻底卸载自带应用方法【步骤】
Win11如何开启系统更新 Win11开启系统更新方法【步骤】
如何在Golang中指定模块版本_使用go.mod控制版本号
ACF 教程:正确更新嵌套在多层 Group 字段内的子字段
如何使用Golang构建基础消息队列模拟_Golang消息发送与消费实现方法
Win11怎么设置屏保_Windows 11屏幕保护程序开启与设置【详解】
如何使用正则表达式批量替换重复的星号-短横模式为固定字符串
MAC怎么用连续互通相机里的“桌上视角”_MAC在视频通话中同时展示人脸和桌面
Python函数缓存机制_lru_cache解析【指导】
php文件怎么变mp4保存_php输出视频流保存为mp4操作【操作】
Mac如何彻底清理浏览器缓存?(Safari与Chrome)
用lighttpd能运行php吗_lighttpd配置php步骤【教程】
Win10系统字体模糊怎么办_Windows10高级缩放设置修复
Win11如何暂停系统更新 Win11暂停更新最长时限设置【步骤】
如何理解Go指针和内存分配关系_Go Pointer内存Model解析
Python面向对象实战讲解_类与设计模式深入理解
PythonPandas数据分析项目教程_时间序列透视表应用
如何在 PHP 中按相同键合并两个关联数组为二维数组
C++如何解析JSON数据?(nlohmann/json库示例)
php下载安装后memory_limit怎么设置_内存限制调整【技巧】
php485在macos下怎么配置_php485 macOS系统配置指南【解答】
Windows11怎么自定义任务栏_Windows11任务栏自定义教程【步骤】
MAC的“接续互通”功能无法使用怎么办_MAC检查蓝牙、Wi-Fi和相同Apple ID登录
Win10如何更改网络连接_Windows10以太网属性IP配置
如何在Golang中实现邮件发送功能_Golang SMTP发送与错误处理示例
网站体验不好=浪费钱:如何提升-用户体验效果差
Python变量绑定机制_引用模型解析【教程】
Win11相机打不开提示错误怎么修_相机权限开启与驱动修复【影像修复】
PHP的FastAdmin架构适合二次开发吗_特点分析【介绍】
mac怎么查看wifi密码_MAC查看已连接WiFi密码方法【技巧】
php会话怎么开启_session_start函数的作用与使用时机【方法】
Windows10如何更改任务栏高度_Win10解除锁定调整大小
Win11怎么连接投影仪_Win11多显示器投屏设置指南【步骤】
Windows如何设置登录时的欢迎屏幕背景?(锁屏界面)
C++ STL算法库怎么用?C++常用算法函数(sort, find)教程【效率提升】
2026-01-02
致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。