【Basic Code】深拷贝、浅拷贝的代码实现(一)
来源:互联网 发布:分卷包数据不正确修复 编辑:程序博客网 时间:2024/06/04 23:23
一、是什么?
在代码中为对象创建副本的技术叫做复制(拷贝),复制分类为浅复制和深复制,前者修改副本中的值类型数据不会修改原对象,但是修改副本中的引用类型数据会修改原对象;后者无论修改副本中的值类型还是引用类型都不会对原对象改动。
二、应用场景
在工作中用到了深复制的代码实现,主要基于不想改变原有数据的完整性,通过DeepClone来解决;同时对于浅复制,我个人认为MVVM中Binding机制里的双向绑定就是这个原理。
暂时理解到这里,欢迎网友们交流在项目中深浅复制的应用以及源码分享交流。
三、怎么玩?
世界上所有的问题没有一个Demo(一顿麻辣烫)解决不了的,解决不了就再来一个(再来一顿)。
由于我工作是敲C#代码,对于Microsoft这个大体系,是通过继承ICloneable接口来实现的,当然这个接口中只有一个Clone方法,实现深、浅复制是还需要我们自己动手的,看代码吧:
1、浅复制:
(1)继承IClone接口,并实现其Clone方法:
class Employee : ICloneable { public string IDCode { get; set; } public string WorkExperience { get; set; } public int Age { get; set; } public Department Department { get; set; } #region IClone 成员 //浅复制的Clone方法实现 public object Clone() { return this.MemberwiseClone(); } #endregion }(2)引用类型Department的类
class Department { public string Name { get; set; } public override string ToString() { return this.Name; } }(3)控制台应用程序的Main方法调用
static void Main(string[] args) { Employee Vincent = new Employee() { IDCode = "11", Age = 24, WorkExperience = "0", Department = new Department() { Name = "TGB" } }; //浅复制 Employee Tom = Vincent.Clone() as Employee; Console.WriteLine("Vincent几个月前的身份:"); Console.WriteLine("ID号码:" + Tom.IDCode); Console.WriteLine("年龄:" + Tom.Age); Console.WriteLine("工作单位:" + Tom.Department); //换行 Console.WriteLine(""); Console.WriteLine("出去实习,开始改变Vincent的身份"); Vincent.IDCode = "102"; Vincent.WorkExperience = "3"; Vincent.Age = 26; Vincent.Department.Name = "乐客VR"; Console.WriteLine("ID号码:" + Tom.IDCode); Console.WriteLine("年龄:" + Tom.Age); Console.WriteLine("工作单位:" + Tom.Department); Console.ReadKey(); }那我自己这个月身份的变化,写了一个小Demo,注意浅复制核心语句是实现ICloneable的Clone方法,程序输出如下:
仔细观察代码,在我将“Employee Tom = Vincent.Clone() as Employee;”之后,第一次输出Tom的信息,和Vincent的一模一样,当我再次改变Vincent的个人信息之后,再次Console 一下Tom的信息发现,工作单位从"TGB"变化成了“乐客VR”,而这个Department对象,恰恰对于Main方法所在的类是个引用,则说明,浅复制在改变值类型后,对备份无影响,但是改变了引用类型,则备份也发生改变,备份不够彻底,就是“浅复制”,姑且这样理解。
2、深复制
继续上面这个例子,修改IClone接口的实现方法,同时将Employee标识为可序列化
#region IClone 成员 //浅复制的Clone方法实现 public object Clone() { using(Stream objectStream = new MemoryStream()) { //先将对象格式化 IFormatter formatter = new BinaryFormatter(); //将其序列化 formatter.Serialize(objectStream, this); //派生类重写时,设置起始位置 objectStream.Seek(0, SeekOrigin.Begin); //反序列化,并形成对象 return formatter.Deserialize(objectStream) as Employee; } } #endregion如图:
此时,就实现了完全复制,即使之后代码修改了引用类型的属性,也不会改变我备份后的结果。
四、总结
上面的方法实现深复制和浅复制,是通过实现Microsoft里的IClone接口,当然这个接口使我们自己来实现的,以上是用过序列化和反序列化实现深复制,是一种不错的方式,下一篇博客,就实战我项目中的一个深复制实现。
- 【Basic Code】深拷贝、浅拷贝的代码实现(一)
- 深拷贝与浅拷贝的实现
- 浅拷贝与深拷贝、以及深拷贝的实现
- string类的简单实现(深拷贝,浅拷贝)
- String类的实现(深拷贝or浅拷贝)
- C++的拷贝构造函数(深拷贝、浅拷贝)
- Java 浅拷贝和深拷贝的代码示例
- object c的浅拷贝(地址拷贝)和深拷贝(对象拷贝)
- c++中类的位拷贝与拷贝构造函数(浅拷贝与深拷贝)
- String类的拷贝(浅拷贝,深拷贝,写时拷贝)
- NumPy的拷贝和视图(完全不拷贝、视图或浅拷贝、深拷贝)
- Java中的深拷贝与浅拷贝(一)
- 【笔试题】深拷贝与浅拷贝(一)
- C++拷贝构造函数(深拷贝,浅拷贝)参考一
- .net 对象浅拷贝和深拷贝的实现
- JavaScript对象的浅拷贝和深拷贝简单实现
- python引用、浅拷贝与深拷贝的实现
- 浅拷贝与深拷贝的区别与实现
- Mac与Phy组成原理的简单分析
- java in acm – 我所知道的一切
- hdu5716 hdu5745 shift-and字符串匹配
- MCU系统时钟
- Ubuntu系统下浏览器和终端的SS代理配置
- 【Basic Code】深拷贝、浅拷贝的代码实现(一)
- poj 3255 Roadblocks(次短路)
- Cocos2d-x ListView 的添加,删除,点击和滑动到头和尾监听
- 交换排序(快速排序 冒泡排序)
- 你不了解的Hacker,实现AngularJS Controller的继承扩展
- C++(继承篇)
- codeforces732a
- zephyr-浮点运算服务
- 轻松搞定面试中的二叉树题目