【C#】深拷贝和浅拷贝、区别

深拷贝和浅拷贝的概念

在 C# 中,深拷贝浅拷贝是两种不同的对象复制方式,用来复制对象中的数据到新的对象。它们的主要区别在于是否会复制对象引用的子对象。

  • 浅拷贝(Shallow Copy)

    • 浅拷贝只复制对象的引用,而不是对象的实际数据内容。
    • 浅拷贝会将对象的所有字段(包括引用类型字段)的引用复制到新对象中。因此,浅拷贝后,原对象和新对象共享相同的引用类型字段。
    • 修改原对象的引用类型字段时,新对象的相应字段也会受到影响。
  • 深拷贝(Deep Copy)

    • 深拷贝会递归地复制对象及其所有引用的对象,从而完全创建一份独立的数据副本。
    • 深拷贝后,新对象和原对象完全独立,修改一个对象不会影响另一个对象。

举例说明

假设我们有一个 ParamSystem 类,其中包含值类型字段和引用类型字段。

public class SubParam
{public int Value { get; set; }
}public class ParamSystem
{public int SystemID1 { get; set; }  // 值类型字段public SubParam SubParam { get; set; }  // 引用类型字段// 构造函数public ParamSystem(int systemID1, int subValue){SystemID1 = systemID1;SubParam = new SubParam { Value = subValue };}// 浅拷贝方法public ParamSystem ShallowCopy(){return (ParamSystem)this.MemberwiseClone();}// 深拷贝方法public ParamSystem DeepCopy(){ParamSystem newCopy = (ParamSystem)this.MemberwiseClone();newCopy.SubParam = new SubParam { Value = this.SubParam.Value };return newCopy;}
}

浅拷贝的实现

在 C# 中,浅拷贝通常使用 MemberwiseClone 方法。MemberwiseClone 会创建一个与当前对象具有相同字段值的新对象,但对于引用类型字段,它只复制引用(不复制实际数据)。

浅拷贝示例
ParamSystem original = new ParamSystem(1, 100);
ParamSystem shallowCopy = original.ShallowCopy();// 修改原对象中的引用类型字段
original.SubParam.Value = 200;Console.WriteLine("Original SubParam.Value: " + original.SubParam.Value);  // 输出:200
Console.WriteLine("Shallow Copy SubParam.Value: " + shallowCopy.SubParam.Value);  // 输出:200
  • 在这里,shallowCopyoriginal 的浅拷贝。
  • 修改 original.SubParam.Value 之后,shallowCopy.SubParam.Value 也发生了变化,因为浅拷贝复制的是 SubParam 的引用,两者指向同一个 SubParam 对象。

深拷贝的实现

深拷贝需要手动复制所有引用类型字段及其内部数据。可以通过递归复制每个引用类型字段来实现,确保每个引用类型字段都是独立的副本。

深拷贝示例
ParamSystem original = new ParamSystem(1, 100);
ParamSystem deepCopy = original.DeepCopy();// 修改原对象中的引用类型字段
original.SubParam.Value = 200;Console.WriteLine("Original SubParam.Value: " + original.SubParam.Value);  // 输出:200
Console.WriteLine("Deep Copy SubParam.Value: " + deepCopy.SubParam.Value);  // 输出:100
  • 在这里,deepCopyoriginal 的深拷贝。
  • 修改 original.SubParam.Value 不会影响 deepCopy.SubParam.Value,因为 deepCopy.SubParam 是一个完全独立的副本。

深拷贝和浅拷贝的代码区别

  1. 浅拷贝只需要调用 MemberwiseClone(),不需要手动复制引用类型字段。
  2. 深拷贝需要手动复制引用类型字段的内容,而不是仅复制引用。如果引用类型字段本身包含引用,还需要递归地深拷贝。

更通用的深拷贝方法:序列化

如果类及其所有字段都支持序列化(即带有 [Serializable] 属性),可以使用二进制序列化JSON序列化来实现深拷贝:

使用 JSON 序列化进行深拷贝(需要 System.Text.Json 库)
using System.Text.Json;public ParamSystem DeepCopyWithJson()
{string jsonString = JsonSerializer.Serialize(this);return JsonSerializer.Deserialize<ParamSystem>(jsonString);
}
  • 这种方法使用 JSON 序列化和反序列化来创建一个完全独立的对象副本,非常适合对象复杂、层级较深的情况。

总结

  • 浅拷贝:只复制值类型字段,引用类型字段只复制引用,使用 MemberwiseClone 实现。
  • 深拷贝:递归复制所有引用类型字段,创建完全独立的副本,可以通过手动复制或序列化实现。
  • 推荐方法:如果对象结构简单,可以手动实现深拷贝。如果对象结构复杂且支持序列化,可以使用序列化方法实现深拷贝。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/60280.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring中的 bean 标签中的 factory-bean , factory-method

1.首先说说 factory-method 是指定创造实例的工厂方法&#xff0c;用法&#xff1a; factory-method 和 class 配合使用&#xff0c;这时 factory-method 必须是class所指定的类中的一个静态方法&#xff0c;也就是Spring会直接调用 class 所指定的类的静态工厂方法创建一个实例…

【大数据测试 Elasticsearch — 详细教程及实例】

大数据测试 Elasticsearch — 详细教程及实例 1. Elasticsearch 基础概述核心概念 2. 搭建 Elasticsearch 环境2.1 安装 Elasticsearch2.2 配置 Elasticsearch 3. 大数据测试的常见方法3.1 使用 Logstash 导入大数据3.2 使用 Elasticsearch 的 Bulk API3.3 使用 Benchmark 工具…

简记Vue3(五)—— Pinia

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

C++11语法介绍(1) -- 列表初始化{},左值和右值,右值引用和移动语义,引用折叠,完美转发

目录 1.C11的发展时间线 2.列表初始化 2.1C98传统的{} 2.2C11中的{} 2.3C11中的std::initializer_list 2.3.1vector中initializer list构造的模拟实现 2.3.2以vector为例演示initializer_list版本的构造 3.右值引用和移动语义 3.1左值和右值 3.2左值引用和右值引用 3.3…

C++编程:利用环形缓冲区优化 TCP 发送流程,避免 Short Write 问题

文章目录 1. 什么是 Short Write 问题&#xff1f;2. 如何解决 Short Write 问题&#xff1f;2.1 方法 1&#xff1a;将 Socket 设置为阻塞模式2.2 方法 2&#xff1a;用户态维护发送缓冲区 3. 用户态维护发送缓冲区实现3.1 核心要点3.2 代码实现3.3 测试程序 参考文档 1. 什么…

集群如何延长作业时间

修改时间 要将作业时间延长1天&#xff0c;可以使用以下命令格式&#xff0c;将 TimeLimit 设置为1-00:00:00&#xff0c;表示延长1天&#xff1a; scontrol update jobid<job_id> TimeLimit1-00:00:00在此格式中&#xff1a; 1-00:00:00 表示1天0小时0分钟0秒。 如何…

第十三届交通运输研究(上海)论坛┆智能网联汽车技术现状与研究实践

0.简介 交通运输研究&#xff08;上海&#xff09;论坛&#xff08;简称为TRF&#xff09;是按照国际会议的组织原则&#xff0c;为综合交通运输领域学者们构建的良好合作交流平台。交通运输研究&#xff08;上海&#xff09;论坛已经成功举办了十二届&#xff0c;凝聚了全国百…

SpringBoot开发——Spring Boot 3种定时任务方式

文章目录 一、什么是定时任务二、代码示例1、 @Scheduled 定时任务2、多线程定时任务3、基于接口(SchedulingConfigurer)实现动态更改定时任务3.1 数据库中存储cron信息3.2 pom.xml文件中增加mysql依赖3.3 application.yaml文件中增加mysql数据库配置:3.4 创建定时器3.5 启动…

CMS那点事

大家好&#xff0c;今天我们来深入探讨JVM垃圾回收机制中备受关注的老年代垃圾回收器——CMS&#xff08;Concurrent Mark Sweep&#xff09;。 CMS垃圾回收算法&#xff1a;标记-清理 CMS的核心算法是标记-清理。简单来说&#xff0c;它分为两个主要步骤&#xff1a; 标记&a…

中仕公考:大三大四考公备考时间线

大三大四想要考公务员的可以借鉴以下时间线&#xff1a; 大三下学期&#xff1a; 基础看课阶段&#xff0c;刚开始先打好基础很重要&#xff0c;根据课程和教材理解知识点&#xff0c;按照模块学习&#xff0c;对考试科目的题型有深入的认识和掌握。 大四初&#xff1a; 强…

Android Studio 将项目打包成apk文件

第一步&#xff1a;选择Build -> Generate Signed APK 会出现&#xff1a; 我们选择 Create new… 然后选择你要存放密钥的地方 点击ok之后&#xff0c;则选择好了文件&#xff0c;并生成了jks文件了。 点击ok之后&#xff0c; 会出现&#xff1a; 选择release&#xf…

股票投资学习路线图

股票投资指南 一、深度解析股票特性 业绩周期视角&#xff1a; 每支股票都有其独特属性&#xff0c;识别周期股、游资股与白马股&#xff0c;洞察不同阶段的最佳投资策略。 市场地位剖析&#xff1a; 掌握龙头&#xff08;正龙、补位、卡位&#xff09;、前排、中军、后排…

FFmpeg存放压缩后的音视频数据的结构体:AVPacket简介,结构体,函数

如下图的解码流程&#xff0c;AVPacket中的位置 FFmpeg源码中通过AVPacket存储压缩后的音视频数据。它通常由解复用器&#xff08;demuxers&#xff09;输出&#xff0c;然后作为输入传递给解码器。 或者从编码器作为输出接收&#xff0c;然后传递给多路复用器&#xff08;mux…

纺织品缺陷检测

项目源码获取方式见文章末尾&#xff01; 600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【基于CNN-RNN的影像报告生成】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模型实现…

SSM房屋销售管理系统-计算机毕业设计源码49529

摘 要 随着国民生活水平的提高&#xff0c;人们日益重视休闲旅游&#xff0c;而互联网的普及也为房屋销售管理带来了新的机遇。将房屋租赁产业与互联网相结合&#xff0c;利用 SSM 框架建设房屋销售管理系统&#xff0c;实现房屋销售管理的网络化&#xff0c;对提高国民经济发展…

2023年09月中国电子学会青少年软件编程(Python)等级考试试卷(三级)答案 + 解析

青少年软件编程(Python)等级考试试卷(三级) 一、单选题(共25题,共50分) 有一组数据存在列表中,things=[“桌子”,“椅子”,“茶几”,“沙发”,“西瓜”,“苹果”,“草莓”,“香蕉”],若想要输出其中的水果数据,则下列处理恰当的是?( )A. print(things) B. print(t…

docker进行SRS直播服务器搭建

docker进行SRS直播服务器搭建 docker构建参考地址: 地址&#xff1a; https://github.com/ossrs/srs https://ossrs.net/lts/zh-cn/docs/v5/doc/getting-started docker run --rm -it -p 1935:1935 -p 1985:1985 -p 8080:8080 \-p 8000:8000/udp -p 10080:10080/udp ossrs/sr…

【PLC一体机】触摸屏上一直显示ERR警示灯的原因和解决方法

博主之前买了一个PLC一体机&#xff0c;在触摸屏上有ERR、RUN和SYS三个显示灯&#xff08;如下图&#xff09; 其中触摸屏工作时&#xff0c;RUN显示灯会显示为绿色&#xff0c;证明触摸屏正常工作。 SYS是触摸屏上刷写PLC程序和触摸屏程序时&#xff0c;会显示为橙色&#xf…

(十四)JavaWeb后端开发——MyBatis

目录 1.MyBatis概述 2.MyBatis简单入门 3.JDBC&#xff08;了解即可&#xff09; 4.数据库连接池​ 5.lombok 6.MyBatis基本操作 7.XML映射文件 8.动态SQL 8.1 if标签 8.2 foreach标签 8.3 sql/include标签​ 1.MyBatis概述 MyBatis是一款优秀的持久层&#xff08…

Elasticsearch可视化工具Elasticvue插件用法

目录 1.打开浏览器扩展程序(示例Edge浏览器) ​2.搜索elasticvue并安装 3.打开elasticvue ​4.连接Es 5.有些浏览器无法下载安装扩展&#xff0c;例如谷歌。可以打包扩展给别的浏览器使用。 5.1打开浏览器扩展&#xff0c;打开开发人员模式&#xff0c;记住扩展程序id 5…