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,一经查实,立即删除!

相关文章

MySQL数据库入门之视图、存储过程、触发器

一、视图&#xff1a; 1.1、视图是什么&#xff1f;怎么理解&#xff1f; 视图是从数据库的基本表&#xff08;或者视图&#xff09;导出的虚表&#xff08;数据库只放定义&#xff0c;它不实际存储数据&#xff0c;而是根据用户定义的SQL查询动态生成的结果集&#xff0c;具…

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&#…

信息安全法律法规复习

第一章 绪论 信息&#xff1a;通过在数据上施加某些约定而赋予这些数据的特殊含义 信息安全&#xff1a;保护信息系统的硬件、软件及相关数据&#xff0c;使其不因为偶然或者恶意侵犯而遭受破坏、更改&#xff0c;泄露&#xff0c;保证信息系统能够连续可靠正常地运行 五大…

探索 CSS、Sass 和 SCSS:区别与应用

在前端开发中&#xff0c;样式设计是不可或缺的一部分&#xff0c;而 CSS&#xff08;Cascading Style Sheets&#xff09;、Sass&#xff08;Syntactically Awesome Stylesheets&#xff09;和 SCSS&#xff08;Sassy CSS&#xff09;是其中最常用的三种工具。 一、CSS&#x…

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…

什么是JavaScript渗透测试?

JavaScript开发的WEB应用和PHP&#xff0c;JAVA, NET等区别在于即没有源代码&#xff0c;也可以通过浏览器查看源代码。 所以相当于JavaScript开发的WEB应用属于白盒测试(默认有源码参考)

视觉SLAM-基本原理

以视觉传感器作为感知方式的SLAM称为视觉SLAM。按照建图稀疏程度来分&#xff0c;视觉SLAM技术可以分为稀疏SLAM&#xff0c;半稠密SLAM和稠密SLAM。虽然同为SLAM系统&#xff0c;但它们的侧重点并不完全一样。SLAM 系统最初的设想是为机器人提供在未知环境中探索时的定位和导航…

如何识别和使用GRS证书

申请TC时的问题 1.没有及时添加分包商信息&#xff0c;TC无法申请 申请TC前&#xff0c;承担“染色”加工的分包商没有增加到GRS证书上&#xff1b; 2.发票地址不在证书上&#xff0c;TC无法申请 公司办公地址与注册地址不同时&#xff0c;证书上没有开票单位的地址&#xff1b…

舆情公关是什么?如何处理企业网络舆情?

舆情就是舆论的情况&#xff0c;在公关领域有暗指负面舆论的意思。总之&#xff0c;舆情公关是目前公关领域的重要分支&#xff0c;很多企业在舆情公关方面折戟&#xff0c;目前越来越多的企业开始重视舆情公关&#xff0c;成为企业一项常规的工作。 什么是舆情公关&#xff1f…

大模型框架:vLLM

目录 一、vLLM 介绍 二、安装 vLLM 2.1 使用 GPU 进行安装 2.2 使用CPU进行安装 2.3 相关配置 三、使用 vLLM 3.1 离线推理 3.2 适配OpenAI-API的API服务 一、vLLM 介绍 vLLM是伯克利大学LMSYS组织开源的大语言模型高速推理框架。它利用了全新的注意力算法「PagedAtten…

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…

Java-RabbitMQ

RabbitMQ使用场景 1、跨系统异步通信 2、多应用之间解耦 3、应用内流程同步变异步 4、整体架构即采用消息驱动 5、应用内部解耦 RabbitMQ内部角色 角色简介生产者消息创建者消费者消息接收者代理RabbitMQ本身&#xff0c;用于存储转发消息&#xff0c;快递功能 RabbitMQ有哪…

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;让…

Java---图书管理系统(练习版)

1.主函数 import book.Book; import book.BookList; import user.AdminUser; import user.NormalUser; import user.User;import java.util.Scanner;public class Main {public static User Login(){//确认你的身份System.out.println("请输如你的名字");Scanner sc…

Elasticsearch集群搭建学习

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