C#浅拷贝和深拷贝数据
目录
一、浅拷贝
二、深拷贝
一、浅拷贝
就是把原来的数据,复制一份,但是2份数据是共享地址的,修改第一份数据或者修改第二份数据,都会一起改变,这可能不是我们程序中需要的场景。
下面我们演示一下,首先建立一个树结构的数据类型,其他类型也可以
1.建立项目
2.建立树结构数据
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace WpfApp4
{public class TestData1{public int ID { get; set; }public string D1 { get; set; }public string D2 { get; set; }public TestData2 testData2 { get; set; }}public class TestData2{public int ID { get; set; }public string D1 { get; set; }public string D2 { get; set; }public TestData3 testData3 { get; set; }}public class TestData3{public int ID { get; set; }public string D1 { get; set; }public string D2 { get; set; }}
}
2.效果
此时testData1的值,呈现树结构显示
把testData1的值赋值给test1后,依然呈现树结构显示
当修改testData1的D1的值后,test1的D1的值也改变了
这个就是浅拷贝,这种拷贝在程序场景中很少用到,不知道的人,偶尔会很奇怪。
二、深拷贝
就是把原来的数据,复制一份,但是2份数据不是共享地址的,修改第一份数据或者修改第二份数据,不会一起改变,这种场景大部分是我们程序中需要的场景。
前面的数据结构依然不变,深拷贝在程序中运用的场景非常多,我们说4种方法。
1.反射实现
可见,修改testData1的D1的值后,test2的D1的值,并没有变化,这正是我们需要的,后续可以对testData1和test2的数据,分别进行业务操作。
2.JSON字符串序列化
此处需要使用Newtonsoft.Json这个包
这里我们首先是先把对象转成字符串,再把字符串转成对象,效果和上面是一样的。
补充:也可以使用Net6中自带的序列化,需要引用System.Text.Json
效果一样,代码如下:
var test31 = JsonSerializer.Deserialize<TestData1>(JsonSerializer.Serialize(testData1)); //首先是先把对象转成字符串,再把字符串转成对象testData1.D1 = "我修改了";
3.表达式树
和上面的效果一样。
4.AutoMapper
这个是第三方的,也可以使用其他的对象映射
此时我们需要先安装
安装完成后,第一句代码,需要进行配置,然后直接调用即可
可见,效果都是一样的。
代码:
using AutoMapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using static WpfApp4.MainWindow;
using Expression = System.Linq.Expressions.Expression;namespace WpfApp4
{/// <summary>/// Interaction logic for MainWindow.xaml/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();TestData3 testData3 = new TestData3();testData3.ID = 3;testData3.D1 = "3.1";testData3.D2 = "3.2";TestData2 testData2 = new TestData2();testData2.ID = 2;testData2.D1 = "2.1";testData2.D2 = "2.2";testData2.testData3 = testData3;TestData1 testData1 = new TestData1();testData1.ID = 1;testData1.D1 = "1.1";testData1.D2 = "1.2";testData1.testData2 = testData2;#region 浅拷贝演示浅拷贝演示,把testData1复制一份//TestData1 test1 = testData1;修改test1的值,那么testData1的值也会变化//testData1.D1 = "我修改了";#endregion#region 深拷贝演示//1.反射//var test2 = DeepCopyWithReflection(testData1);//testData1.D1 = "我修改了";//2.JSON字符串序列化//var test3 = JsonConvert.DeserializeObject<TestData1>(JsonConvert.SerializeObject(testData1)); //首先是先把对象转成字符串,再把字符串转成对象//testData1.D1 = "我修改了";//var test31 = JsonSerializer.Deserialize<TestData1>(JsonSerializer.Serialize(testData1)); //首先是先把对象转成字符串,再把字符串转成对象//testData1.D1 = "我修改了";//3.表达式树//var test4 = TransExp<TestData1, TestData1>.Trans(testData1);//testData1.D1 = "我修改了";//4.AutoMappervar config = new MapperConfiguration(cfg => cfg.CreateMap<TestData1, TestData1>());//映射配置var test5 = config.CreateMapper().Map<TestData1>(testData1);testData1.D1 = "我修改了";#endregion}/// <summary>/// 利用反射实现深拷贝/// </summary>/// <typeparam name="T"></typeparam>/// <param name="obj"></param>/// <returns></returns>public static T DeepCopyWithReflection<T>(T obj){Type type = obj.GetType();// 如果是字符串或值类型则直接返回if (obj is string || type.IsValueType) return obj;// 如果是数组if (type.IsArray){Type elementType = Type.GetType(type.FullName.Replace("[]", string.Empty));var array = obj as Array;Array copied = Array.CreateInstance(elementType, array.Length);for (int i = 0; i < array.Length; i++){copied.SetValue(DeepCopyWithReflection(array.GetValue(i)), i);}return (T)Convert.ChangeType(copied, obj.GetType());}object retval = Activator.CreateInstance(obj.GetType());PropertyInfo[] properties = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic| BindingFlags.Instance | BindingFlags.Static);foreach (var property in properties){var propertyValue = property.GetValue(obj, null);if (propertyValue == null)continue;property.SetValue(retval, DeepCopyWithReflection(propertyValue), null);}return (T)retval;}/// <summary>/// 表达式树/// </summary>/// <typeparam name="TIn"></typeparam>/// <typeparam name="TOut"></typeparam>public static class TransExp<TIn, TOut>{private static readonly Func<TIn, TOut> cache = GetFunc();private static Func<TIn, TOut> GetFunc(){ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn), "p");List<MemberBinding> memberBindingList = new List<MemberBinding>();foreach (var item in typeof(TOut).GetProperties()){if (!item.CanWrite) continue;MemberExpression property = Expression.Property(parameterExpression, typeof(TIn).GetProperty(item.Name));MemberBinding memberBinding = Expression.Bind(item, property);memberBindingList.Add(memberBinding);}MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TOut)), memberBindingList.ToArray());Expression<Func<TIn, TOut>> lambda = Expression.Lambda<Func<TIn, TOut>>(memberInitExpression, new ParameterExpression[] { parameterExpression });return lambda.Compile();}public static TOut Trans(TIn tIn){return cache(tIn);}}}
}
本案例代码:
https://download.csdn.net/download/u012563853/88637534
来源:
C#浅拷贝和深拷贝数据-CSDN博客
相关文章:
C#浅拷贝和深拷贝数据
目录 一、浅拷贝 二、深拷贝 一、浅拷贝 就是把原来的数据,复制一份,但是2份数据是共享地址的,修改第一份数据或者修改第二份数据,都会一起改变,这可能不是我们程序中需要的场景。 下面我们演示一下,首…...
【JVM】4.运行时数据区(程序计数器、虚拟机栈)
文章目录 4.JVM的运行时数据区4.1 程序计数器4.2 Java虚拟机栈4.3 虚拟机栈内存溢出 4.JVM的运行时数据区 4.1 程序计数器 程序计数器(PC)会记录着下一行字节码指令的地址。执行完当前指令后,PC刷新,JVM的执行引擎根据程序计数器…...
算法:程序员的数学读书笔记
目录 0的故事 一、按位计数法 二、不使用按位计数法的罗马数字 三、十进制转二进制 四、0所起到的作用 逻辑 一、为何逻辑如此重要 二、兼顾完整性和排他性 三、逻辑 四、德摩根定律 五、真值表 六、文氏图 七、卡诺图 八、逻…...
机器学习算法---时间序列
类别内容导航机器学习机器学习算法应用场景与评价指标机器学习算法—分类机器学习算法—回归机器学习算法—聚类机器学习算法—异常检测机器学习算法—时间序列数据可视化数据可视化—折线图数据可视化—箱线图数据可视化—柱状图数据可视化—饼图、环形图、雷达图统计学检验箱…...
RK3568/RV1126/RV1109/RV1106 ISP调试方案
最近一直在做瑞芯微rv1126的开发,由于项目性质,与camera打的交道比较多,包括图像的采集,ISP处理,图像处理,H.264/H.265编解码等各个方面吧。学到了不少,在学习的过程中,也得到了不少…...
【TB作品】51单片机,语音出租车计价器
西交大题目 1.语音出租车计价器 一、功能要求: 1.具有可模拟出租车车轮转速传感器的硬件设计,可计量出租车所走的公 里数。 2.显示和语音播报里程、价格和等待红灯或堵车的计时价格: 3.具有等待计时功能 4.具有实时年月日显示和切换功能。 5.操作简单、界面友好。 二、设计建议…...
jmeter简单压测kafka
前言 这也是一个笔记,就是计划用jmeter做性能测试,但是这里是只要将数据放到kafka的topic里,后面查看下游业务处理能力。 一、方案 因为只要实现数据放到kafka,参考了下博友的方案,可行。 二、方案验证 详细过程就不…...
【漏洞复现】红帆OA iorepsavexml.aspx文件上传漏洞
漏洞描述 广州红帆科技深耕医疗行业20余年,专注医院行政管控,与企业微信、阿里钉钉全方位结合,推出web移动一体化办公解决方案——iOffice20(医微云)。提供行政办公、专业科室应用、决策辅助等信息化工具,采取平台化管理模式,取代医疗机构过往多系统分散式管理,实现医…...
04_Web框架之Django一
Web框架之Django一 学习目标和内容 1、能够描述Django的作用 2、能够使用Django创建应用 3、能够使用GET和POST请求方式进行传参 4、能够使用Django的函数式方法定义视图 5、能够进行Django的配置文件修改 6、能够基本使用Django的路由定义 一、Django相关介绍 1、什么是Djan…...
单机架构到分布式架构的演变
目录 1.单机架构 2.应用数据分离架构 3.应用服务集群架构 4.读写分离 / 主从分离架构 5.引入缓存 —— 冷热分离架构 6.垂直分库 7.业务拆分 —— 微服务 8.容器化引入——容器编排架构 总结 1.单机架构 初期,我们需要利用我们精干的技术团队,快…...
1.新入手的32位单片机资源和资料总览
前言: 学了将近1年的linux驱动和uboot,感觉反馈不足,主要是一直在学各种框架,而且也遇到了门槛,比如驱动部分,还不能随心所欲地编程,原因是有些外设的原理还不够深刻、有些复杂的底层驱动的代码…...
jmeter判断’响应断言‘两个变量对象是否相等
1、首先需要设置变量,json、正则、csv文件等变量 2、然后在响应断言中 ①JMeter Variable Name to use —— 输入一个变量,变量名即可 ② 模式匹配规则 ——相等 ③测试模式 ——输入引用的变量命${变量名} (注意这里是需要添加一个测试模式…...
【Linux基础命令使用】
文章目录 一. 操作系统和文件及文件路径介绍二. 基础指令介绍三. 结束语 一. 操作系统和文件及文件路径介绍 什么是操作系统?操作系统是一款进行软硬件资源管理的软件为什么要进行软硬件资源管理?对上提供良好的稳定的运行服务----工具Linux指令和图形化…...
【JNA与C++基本使用示例】
JNA中java与C使用注意事项和代码示例 JNA关系映射表使用案列注意代码示例C代码java代码 JNA关系映射表 使用案列 注意 JNA只支持C方式的dll使用C的char* 作为返回值时,需要返回的变量为malloc分配的地址C的strlen函数只获得除/0以外的字符串长度 代码示例 C代码…...
HttpRunner接口自动化测试框架
简介 HttpRunner是一款面向 HTTP(S) 协议的通用测试框架,只需编写维护一份 YAML/JSON 脚本,即可实现自动化测试、性能测试、线上监控、持续集成等多种测试需求。 项目地址:GitHub - httprunner/httprunner: HttpRunner 是一个开源的 API/UI…...
云计算:Vmware 安装 FreeNAS
目录 一、实验 1.Vmware 安装 FreeNAS 2.配置Web界面 二、问题 1.iSCSI如何限定名称 2.LUN和LVM的区别 一、实验 1.Vmware 安装 FreeNAS (1)环境准备 VMware Workstation 17 FreeNAS相关安装部署镜像: 官网地址: https://download…...
数据库交付运维高级工程师-腾讯云TDSQL
数据库交付运维高级工程师-腾讯云TDSQL上机指导,付费指导,暂定99...
目标检测YOLO实战应用案例100讲-光伏电站热斑检测(续)
目录 2.5 图像重建方法实验及其结果分析 2.5.1 数据集与超参数 2.5.2 结果分析...
jmeter如何循环运行到csv文件最后一行后停止
1、首先在线程组中设置’循环次数‘–勾选永远 2、csv数据文件设置中设置: 遇到文件结束符再次循环?——改为:False 遇到文件结束符停止线程?——改为:True 3、再次运行就会根据文档的行数运行数据 (如果需要在循环控制器中&…...
电路中的屏蔽罩作用及设计
1.1 屏蔽罩作用 1.1.1 屏蔽电子信号,防止外界的干扰或内部向外的辐射: 一般见于通信类电路PCB,主要一个无线通信产品上有的敏感器件、模拟、数字电路、DCDC电源电路,都需屏蔽隔离,是为了不影响其它电路,也有防止其它电…...
CodeBlocks定义异常:multiple definition of 和 first defined here
基于链表实现贪吃蛇案例时候,在CodeBlocks的CPP源文件定义函数和全局变量均报错 异常现象 在**自定义的cpp**文件定义全局变量、对象、函数等均出现重复定义和首次定义 multiple definition of Controller::showCopy() first defined here 异常解决方案 正确代码…...
RHEL7.5编译openssl1.1.1w源码包到rpm包
openssl1.1.1w下载地址 https://www.openssl.org/source/ 安装依赖包 yum -y install curl which make gcc perl perl-WWW-Curl rpm-build wget http://mirrors.aliyun.com/centos-vault/7.5.1804/os/x86_64/Packages/perl-WWW-Curl-4.15-13.el7.x86_64.rpm rpm -ivh pe…...
结构型设计模式(二)装饰器模式 适配器模式
装饰器模式 Decorator 1、什么是装饰器模式 装饰器模式允许通过将对象放入特殊的包装对象中来为原始对象添加新的行为。这种模式是一种结构型模式,因为它通过改变结构来改变被装饰对象的行为。它涉及到一组装饰器类,这些类用来包装具体组件。 2、为什…...
C#数据结构
C#数据结构 常见结构 1、集合 2、线性结构 3、树形结构 4、图形结构 Array/ArrayList/List 特点:内存上连续存储,节约空间,可以索引访问,读取快,增删慢 using System; namespace ArrayApplication {class MyAr…...
代码随想Day39 | 62.不同路径、63. 不同路径 II
62.不同路径 每次向右或者向下走两个选择,定义dp数组dp[i][j] 为到达索引ij的路径和,状态转移公式为 dp[i][j]dp[i-1][j]dp[i][j-1],初始状态的第一行和第一列为1,从左上到右下开始遍历即可。详细代码如下: class Sol…...
Autosar通信实战系列07-Com模块要点及其配置介绍(二)
本文框架 前言1. ComGeneral配置2. ComConfig配置2.1 ComGwMapping2.2 ComIPdus2.3 ComIPduGroups2.4 ComIPduSignals2.5 ComIPduSignalGroups2.6 ComTimeBasis前言 在本系列笔者将结合工作中对通信实战部分的应用经验进一步介绍常用,包括但不限于通信各模块的开发教程,代码…...
DSP捕获输入简单笔记
之前使用stm32的大概原理是: 输入引脚输入一个脉冲,捕获1开始极性捕获,捕获的是从启动捕获功能开始计数,捕获的是当前的计数值; 例如一个脉冲,捕获1捕获上升沿,捕获2捕获下降沿;而两…...
【Java基础】HashMap 原理
文章目录 1、HashMap 设置值的原理2、HashMap 获取值原理3、HashMap Hash优化4、HashMap 寻址优化5、HashMap 是如何解决Hash冲突的?5.1 get数据的时候,如果定位到指定位置的元素是一个链表,怎么办呢?5.2 红黑树 6、数组扩容6.1 数…...
vue3的大致使用
<template><div class"login_wrap"><div class"form_wrap"> <!-- 账号输入--> <el-form ref"formRef" :model"user" class"demo-dynamic" > <!--prop要跟属性名称对应-->…...
什么是计算机网络?计算机网络基础知识
1.网络的组成部分:由主机,路由器,交换机等组成 2.网络结构:网络的网络 3.信息交换方式:电路交换和分组交换 4.网络分层:分清职责,物理层,链路层,网络层,运…...
大连中山区网站建设/大庆黄页查询电话
前言 首先说明,对于JavaScript这门脚本语言,我是个菜鸟。虽然也写过不少JavaScript代码,但一直是不求甚解,直到最近才开始系统学习这门语言。学习的原因是我即将毕业,过了年就要正式工作了,而我要入职的职位…...
如何做网站淘宝客/培训机构招生方案模板
首先,是曾经的讲师LH大佬的模板 主要涉及了常用的文件头以及一些常用语句和函数的缩写 #include<cstdio> #include<iostream> #include<cstdlib> #include<iomanip> #include<cmath> #include<cstring> #include<string>…...
富阳网站/泉州百度seo
闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域 说明: 关于闭包,即函数定义和函数表达…...
成都企业网站优化/建一个app平台的费用多少
在JAVA编程中,JAVA提供了8种基本数据类型,分别是int、byte、short、long、float、double、char、boolean,除此之外,其它的都是对象引用,如:数组和字符串。当定义基本数据类型变量时,其格式&…...
做网站fjfzwl/网站自己推广
1、安装编译环境 1.基础环境 yum update yum groupinstall "Development Tools" 2.gettext更新 gettext 版本大于0.18可以跳过 gettext -V 编译安装: wget https://ftp.gnu.org/pub/gnu/gettext/gettext-0.21.tar.gz --no-check-certificate &…...
英文二手汽车网站建设/潍坊网站建设咨询
织梦500内部服务器错误一般是iis环境的小伙伴才会遇到,织梦的500错误一般是因为这2个原因引起的 第一个500错误原因:你网站织梦程序版本太低而你主机PHP版本过高 1、先查看你网站程序是织梦什么版本的 打开 /data/admin/ver.txt 文件查看,例…...