C# 深拷贝和浅拷贝

文章目录

  • 1.深拷贝
  • 2.浅拷贝
  • 3.拷贝类
  • 4.浅拷贝的实现
  • 5.深拷贝实现
    • 5.1 浅拷贝对象,对引用类型重新一个个赋值
    • 5.2 反射实现
    • 5.3 利用XML序列化和反序列化实现

1.深拷贝

拷贝一个对象时,不仅仅把对象的引用进行复制,还把该对象引用的值也一起拷贝。这样进行深拷贝后的拷贝对象就和源对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。

int source = 123;
// 值类型赋值内部执行深拷贝
int copy = source;
// 对拷贝对象进行赋值不会改变源对象的值
copy = 234;
Console.WriteLine($"source = {source},copy = {copy}");  // 123 234
// 同样对源对象赋值也不会改变拷贝对象的值
source = 345;
Console.WriteLine($"source = {source},copy = {copy}");  // 345 234

深拷贝示意图:
在这里插入图片描述

2.浅拷贝

==拷贝一个对象时,仅仅拷贝对象的引用进行拷贝,但是拷贝对象和源对象还是引用同一份实体。==此时,其中一个对象的改变都会影响到另一个对象。

public class Person
{public string Name { get; set; }
}public static void Main(string[] args)
{Person sourceP = new Person() { Name = "张三" };Person copyP = sourceP; // 浅拷贝copyP.Name = "张老三";  // 拷贝对象改变Name值,源对象Name值也会改变Console.WriteLine("Person.Name: [SourceP: {0}] [CopyP:{1}]", sourceP.Name, copyP.Name); // 张老三 张老三
}

浅拷贝示意图:
在这里插入图片描述

3.拷贝类

//年级
public class Grade
{public int Stu_Grade { get; set; }
}//学生
public class Student
{public string Name { get; set; }public int Age { get; set; }public Grade Grade { get; set; }// 调用Object的MemberwiseClone方法实现浅拷贝public Student ShallowCopy(){return (Student)this.MemberwiseClone();}// 输出学生信息public override string ToString(){return $"姓名:{Name},年龄:{Age},年纪:{Grade.Stu_Grade}";}
}

4.浅拷贝的实现

浅拷贝的实现是调用受保护的方法Object.MemberwiseClone()

public static void Main(string[] args)
{Student sourceStu = new Student{Name = "ming",Age = 18,Grade = new Grade{ Stu_Grade = 6 }};Student copyStu = sourceStu.ShallowCopy();// 输出修改信息前,源学生和拷贝学生信息Console.WriteLine("------修改前------");Console.WriteLine("源学生信息" + sourceStu.ToString());Console.WriteLine("拷贝信息" + copyStu.ToString());copyStu.Name = "Tom";copyStu.Age = 26;copyStu.Grade.Stu_Grade = 10;// 输出修改信息后,源学生和拷贝学生信息Console.WriteLine("------修改后------");Console.WriteLine("源学生信息" + sourceStu.ToString());Console.WriteLine("拷贝信息" + copyStu.ToString());
}

输出:

------修改前------
源学生信息姓名:ming,年龄:18,年级:6
拷贝信息姓名:ming,年龄:18,年级:6
------修改后------
源学生信息姓名:ming,年龄:18,年级:10
拷贝信息姓名:Tom,年龄:26,年级:10

5.深拷贝实现

5.1 浅拷贝对象,对引用类型重新一个个赋值

public Student DeepCopy()
{Student student = (Student)this.MemberwiseClone();student.Grade = new Grade{ Stu_Grade = student.Grade.Stu_Grade };return student;
}

采用和浅拷贝一样的测试数据进行测试,输出:

------修改前------
源学生信息姓名:ming,年龄:18,年级:6
拷贝信息姓名:ming,年龄:18,年级:6
------修改后------
源学生信息姓名:ming,年龄:18,年级:6
拷贝信息姓名:Tom,年龄:26,年级:10

5.2 反射实现

拷贝对象:

//年级
public class Grade
{public int Stu_Grade { get; set; }
}// 成绩
public class Score
{public Science Science { get; set; }public Arts Arts { get; set; }
}// 理科
public class Science
{// 数学public int Math { get; set; }
}// 文科
public class Arts
{// 语文public int Chinese { get; set; }
}//学生
public class Student
{public string Name { get; set; }public int Age { get; set; }public Grade Grade { get; set; }public Score Scroe { get; set; }
}

深拷贝实现:

public class DeepCopyHelper
{// 反射实现深拷贝public static T DeepCopyByReflect<T>(T obj){//如果是字符串或值类型则直接返回if (obj is string || obj.GetType().IsValueType) return obj;object retval = Activator.CreateInstance(obj.GetType());FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);foreach (FieldInfo field in fields){// 解决层次引用类型try { field.SetValue(retval, DeepCopyByReflect(field.GetValue(obj))); }catch { }}return (T)retval;}
}

测试:

public static void Main(string[] args)
{Student sourceStu = new Student{Name = "ming",Age = 18,Grade = new Grade{ Stu_Grade = 6 },Scroe = new Score{ Arts = new Arts{Chinese = 90}, Science = new Science{Math = 90}}};Student copyStu = DeepCopyHelper.DeepCopyByReflect<Student>(sourceStu);// 输出修改信息前,源学生和拷贝学生信息Console.WriteLine("------修改前------");Console.WriteLine("源学生信息" + sourceStu.ToString());Console.WriteLine("拷贝信息" + copyStu.ToString());copyStu.Name = "Tom";copyStu.Age = 26;copyStu.Grade.Stu_Grade = 10;copyStu.Scroe.Arts.Chinese = 100;copyStu.Scroe.Science.Math = 100;// 输出修改信息后,源学生和拷贝学生信息Console.WriteLine("------修改后------");Console.WriteLine("源学生信息" + sourceStu.ToString());Console.WriteLine("拷贝信息" + copyStu.ToString());
}

结果:

------修改前------
源学生信息姓名:ming,年龄:18,年级:6, 成绩:(语文:90,数学:90)
拷贝信息姓名:ming,年龄:18,年级:6, 成绩:(语文:90,数学:90)
------修改后------
源学生信息姓名:ming,年龄:18,年级:6, 成绩:(语文:90,数学:90)
拷贝信息姓名:Tom,年龄:26,年级:10, 成绩:(语文:100,数学:100)

5.3 利用XML序列化和反序列化实现

测试内容和结果和5.2一样

// xml 实现深拷贝
public static T DeepCopyByXml<T>(T obj)
{object retval;using (MemoryStream ms = new MemoryStream()){XmlSerializer xml = new XmlSerializer(typeof(T));xml.Serialize(ms, obj);ms.Seek(0, SeekOrigin.Begin);retval = xml.Deserialize(ms);ms.Close();}return (T)retval;
}

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

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

相关文章

python期末作业:批量爬取站长之家的网站排行榜数据并保存,数据分析可视化

爬虫作业,含python爬取数据和保存文件,数据分析使用pyecharts做数据可视化 整体上分析网站的排名,直观看各个网站的热度。 数据分析之后大致的效果: 整个项目分为两个大的部分,第一部分就是抓取网站排名数据,然后保存为Excel、csv等格式,其次就是从文件中…

【30天精通Prometheus:一站式监控实战指南】第8天:redis_exporter从入门到实战:安装、配置详解与生产环境搭建指南,超详细

亲爱的读者们&#x1f44b;   欢迎加入【30天精通Prometheus】专栏&#xff01;&#x1f4da; 在这里&#xff0c;我们将探索Prometheus的强大功能&#xff0c;并将其应用于实际监控中。这个专栏都将为你提供宝贵的实战经验。&#x1f680;   Prometheus是云原生和DevOps的…

arc-eager算法XJTU-NLP自然语言处理技术期末考知识点

arc-eager算法&#xff1a;以我/做了/一个/梦为例来描述arc-eager算法的四个操作&#xff1a;shift&#xff0c;left-arc&#xff0c;right-arc&#xff0c;reduce XJTU-NLP期末考点2024版 题型&#xff1a;5*6简答题4*15计算题 简答题考点&#xff1a; &#xff08;1&#…

Java+Spring+ IDEA+MySQL云HIS系统源码 云HIS适合哪些地区的医院?

JavaSpring IDEAMySQL云HIS系统源码云HIS适合哪些地区的医院&#xff1f; 云HIS适合哪些地区的医院&#xff1f; 云HIS&#xff08;云医院信息系统&#xff09;适合多种地区的医院&#xff0c;特别是那些希望实现医疗服务的标准化、信息化和规范化&#xff0c;同时降低IT运营成…

42-2 应急响应之计划任务排查

一、进程排查 进程排查是指通过分析系统中正在运行的进程,以识别和处理恶意程序或异常行为。在Windows和Linux系统中,进程是操作系统的基本单位,因此对于发现和处理恶意软件或异常活动至关重要。恶意程序通常会以进程的形式在系统中运行,执行各种恶意操作,比如窃取信息、破…

每日一题 包含不超过两种字符的最长子串

目录 1.前言 2.题目解析 3.算法原理 4.代码实现 1.前言 首先我打算介绍一下&#xff0c;我对滑动窗口的理解。 滑动窗口可以分为四个步骤&#xff1a; 进窗口&#xff1a; 在这一步骤中&#xff0c;我们决定了要在窗口中维护的信息。例如&#xff0c;在这个问题中&#xff…

Codeforces Round 946 (Div.3)

C o d e f o r c e s R o u n d 946 ( D i v . 3 ) \Huge{Codeforces~Round~946~(Div.3)} Codeforces Round 946 (Div.3) 题目链接&#xff1a;Codeforces Round 946 (Div. 3) 文章目录 Problems A. Phone Desktop题意思路标程 Problems B. Symmetric Encoding题意思路标程 Pr…

ubuntu 配置用户登录失败尝试次数限制

前言&#xff1a; 通过修改pam配置来达到限制密码尝试次数&#xff01; 1&#xff1a;修改 /etc/pam.d/login 配置&#xff08;这里只是终端登录配置&#xff0c;如果还需要配置SSH远程登录限制&#xff0c;只配置下面的 /etc/pam.d/pam.d/common-auth 即可&#xff09; vim…

SpringCloud的Config配置中心,为什么要分Server服务端和Client客户端?

SpringCloud的Config配置中心&#xff0c;为什么要分Server服务端和Client客户端&#xff1f; 在SpringCloud的Config配置中心中分了Server服务端和Client客户端&#xff0c;为什么需要这样分呢&#xff1f;它的思想是所有微服务的配置文件都放到git远程服务器上&#xff0c;让…

Elasticsearch集群搭建学习

Elasticsearch集群聚合、集群搭建 RestClient查询所有高亮算分控制 数据聚合DSL实现Bucket聚合DSL实现Metrics聚合RestAPI实现聚合 拼音分词器如何使用拼音分词器&#xff1f;如何自定义分词器&#xff1f;拼音分词器注意事项&#xff1f; 自动补全数据同步集群搭建ES集群结构创…

蓝桥杯备赛——DP【python】

一、小明的背包1 试题链接&#xff1a;https://www.lanqiao.cn/problems/1174/learning/ 问题描述 输入实例 5 20 1 6 2 5 3 8 5 15 3 3 输出示例 37 问题分析 这里我们要创建一个DP表&#xff0c;DP&#xff08;i&#xff0c;j&#xff09;表示处理到第i个物品时消耗j体…

Atlas 200 DK(Model 3000)安装MindSpore Ascend版本

一、参考资料 mindspore快速安装 二、重要说明 经过博主多次尝试多个版本&#xff0c;Atlas 200 DK&#xff08;Model 3000&#xff09;无法安装MindSpore Ascend版本。 三、准备工作 1. 测试环境 设备型号&#xff1a;Atlas 200 DK(Model: 3000) Operating System Vers…

依赖的各种java库(工具类) :fastjson,lombok,jedis,druid,mybatis等

lombok 功能&#xff1a; Lombok 是一个实用的Java类库&#xff0c;可以通过简单的注解来简化和消除一些必须有但显得很臃肿的Java代码。 导入包&#xff1a;使用Lombok首先要将其作为依赖添加到项目中&#xff0c;在pom.xml文件中手动添加 <dependency><groupId&g…

提取COCO 数据集的部分类

1.python提取COCO数据集中特定的类 安装pycocotools github地址&#xff1a;https://github.com/philferriere/cocoapi pip install githttps://github.com/philferriere/cocoapi.git#subdirectoryPythonAPI若报错&#xff0c;pip install githttps://github.com/philferriere…

【CTF Web】CTFShow web5 Writeup(SQL注入+PHP+位运算)

web5 1 阿呆被老板狂骂一通&#xff0c;决定改掉自己大意的毛病&#xff0c;痛下杀手&#xff0c;修补漏洞。 解法 注意到&#xff1a; <!-- flag in id 1000 -->拦截很多种字符&#xff0c;连 select 也不给用了。 if(preg_match("/\|\"|or|\||\-|\\\|\/|\…

24款奔驰S450升级原厂后排娱乐系统 主动氛围灯有哪些功能

24款奔驰S400豪华升级原厂主动氛围灯与后排娱乐系统&#xff1a;画蛇添足还是锦上添花&#xff1f; 在当今汽车市场竞争激烈的环境下&#xff0c;汽车制造商们为了满足消费者的多元化需求&#xff0c;不断推出各种升级配置和豪华版本。24款奔驰S400豪华版作为奔驰S级的一款重要…

听说部门来了个00后测试开发,一顿操作给我整麻了

公司新来了个同事&#xff0c;听说大学是学的广告专业&#xff0c;因为喜欢IT行业就找了个培训班&#xff0c;后来在一家小公司实习半年&#xff0c;现在跳槽来我们公司。来了之后把现有项目的性能优化了一遍&#xff0c;服务器缩减一半&#xff0c;性能反而提升4倍&#xff01…

uniapp开发vue3监听右滑返回操作,返回到指定页面

想要在uniapp框架中监听左滑或者右滑手势&#xff0c;需要使用touchstart和touchend两个api&#xff0c;因为没有原生的左右滑监听api&#xff0c;所以我们只能依靠这两个api来获取滑动开始时候的x坐标和滑动结束后的x坐标做比对&#xff0c;右滑的话&#xff0c;结束时候的x坐…

飞速提升中文打字,Master of Typing in Chinese for Mac助你一臂之力

Master of Typing in Chinese for Mac是一款专为Mac用户设计的中文打字练习软件。其主要功能包括帮助用户提高打字速度和准确性&#xff0c;培养盲打技巧&#xff0c;使键盘输入更加高效。 打字速度提升&#xff1a;软件提供多种练习模式&#xff0c;如字母、特殊字符、单词和…

FPGA状态机设计详解

一.什么是状态机&#xff1f; 想象一下你正在玩一个电子游戏&#xff0c;角色有多种状态&#xff0c;比如“行走”、“跳跃”、“攻击”等。每当你按下不同的按键或者满足某些条件时&#xff0c;角色的状态就会改变&#xff0c;并执行与该状态对应的动作。这就是状态机的一个简…