浅拷贝和深拷贝
时间:2020-06-10
本文章向大家介绍浅拷贝和深拷贝,主要包括浅拷贝和深拷贝使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
一、浅拷贝:是指将对象中的所有字段逐字复制到一个新对象
(1)对值类型字段只是简单的拷贝一个副本到目标对象,改变目标对象中值类型字段的值不会反映到原始对象中,因为拷贝的是副本
(2)对引用类型字段则是指拷贝他的一个引用到目标对象,改变目标对象中引用类型字段的值会将它反映到原始对象中,因为拷贝的是指向堆是上的一个地址。
二、深拷贝:深拷贝与浅拷贝不同的是对于引用字段的处理,深拷贝会将在新对象中创建一个新的对象和原始对象字段相同的字段,也就是说这个引用和原始对象引用是不同,我们改变新对象这中这个字段的时候是不会影响到原始对象中对应字段的内容。
三、赋值:
(1)引用类型的赋值就是将原来对象的地址给新的对象拷贝一下即可,新对象的修改会影响原始对象。
(2)值类型的复制,就是建立副本,副本和原始数据互不干涉
四、浅拷贝方法
Animal animal1 = new Animal(); animal1.Name = "绿狗"; animal1.Age = 1; Animal animal2= animal1;//浅拷贝 Animal animal3= new Animal(); animal3.Name = animal1.Name; animal3.Age = animal1.Age;//深拷贝
五、深拷贝方法
1、方式一 使用二进制流
using System; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; public static class ObjectCopier { public static T Clone<T>(T source) { if (!typeof(T).IsSerializable) { throw new ArgumentException("The type must be serializable.", "source"); } if (Object.ReferenceEquals(source, null)) { return default(T); } IFormatter formatter = new BinaryFormatter(); Stream stream = new MemoryStream(); using (stream) { formatter.Serialize(stream, source); stream.Seek(0, SeekOrigin.Begin); return (T)formatter.Deserialize(stream); } } }
2、使用序列化与反序列化
public static T CloneJson<T>(this T source) { if (Object.ReferenceEquals(source, null)) { return default(T); } var deserializeSettings = new JsonSerializerSettings {ObjectCreationHandling = ObjectCreationHandling.Replace}; return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source), deserializeSettings); }
3、使用反射
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; }
4、方式四 使用XML序列化与反序列化
public static T DeserializeXML<T>(string xmlData) where T:new() { if (string.IsNullOrEmpty(xmlData)) return default(T); TextReader tr = new StringReader(xmlData); T DocItms = new T(); XmlSerializer xms = new XmlSerializer(DocItms.GetType()); DocItms = (T)xms.Deserialize(tr); return DocItms == null ? default(T) : DocItms; }
更优秀文章参考:https://www.cnblogs.com/zhili/p/DeepCopy.html
原文地址:https://www.cnblogs.com/qtiger/p/13087921.html
- Java Process destroy方法kill进程,返回码测试
- 百度人脸识别API Java调用
- Java Socket Timeout总结
- 求一个数组中子数组的最大和算法(Java实现)
- JDBC批量提交SQL的几点问题解答
- 工具推荐: 汽车CAN总线分析框架CANToolz
- Windows下jps, jconsole无法查看本地java进程问题解决
- DateFormat 线程不安全
- zip文件操作导致JVM crash
- 如何搭建你自己的“深度学习”机器?
- MySQL INSERT INTO...ON DUPLICATE KEY UPDATE的使用
- 通过Java代码来模拟乘法器
- INET_ATON()函数在MySQL5.6版本和5.7版本的差异
- Linux主机之间ssh免密登录配置
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- ZBAR库
- 英文文本关系抽取(fine-tune Huggingface XLNet)
- Laravel 7.x 使用 keyspace notification 监听不到 Key 过期事件
- 嵌入式链接脚本(LINK SCRIPT)介绍
- zbar中的zbar_scan_image 函数
- PM2源码分析
- zbar库中的zbar_scan_y函数
- 快速学习-Nacos Config--服务配置
- C 库函数 - fread()
- pthread_join函数
- 快速学习-Sleuth--链路追踪
- pthread_cancel函数
- SAP WebClient UI开发工具中attribute文件夹展开的实现原理分析
- pthread_attr_init线程属性
- C语言可重入函数和不可重入函数