大话设计模式,让你的代码更完美5---浅复制和深复制
来源:互联网 发布:淘宝网夏装新款女装 编辑:程序博客网 时间:2024/06/05 06:10
当前存在一个对象“张三”,由于需求导致需要我们创建一个类似的对象“李四”,这两个对象都属于Person类,按照以往我们都会通过new的方式去创建“李四”,
但是这样新创建的对象必然会走构造函数,这样会给系统增加诸多开支,降低效率,这时候我们就需要克隆(Clone)。
克隆就是从一个对象创建另外一个可定制的对象,而不需要知道任何创建的细节,不走构造函数等等。
在C#语言中提供了ICloneable接口,实现该接口即实现该接口的Clone方法,该方法的内容一般为下:
public Object Clone() { return (Object)this.MemberwiseClone(); }
在这里要说一点,克隆一般用在初始化信息不发生改变的情况下使用的,这可以隐藏部分细节,提高性能。
MemberwiseClone()方法是浅复制方法:
所谓浅复制方法,即将A对象中的值类型依次复制,A对象中的引用对象只复制其地址,不复制其引用的对象。
例如:
简历对象:
//简历 class Resume : ICloneable { private string name; private string sex; private string age; private WorkExperience work; public Resume(string name) { this.name = name; work = new WorkExperience(); } //设置个人信息 public void SetPersonalInfo(string sex, string age) { this.sex = sex; this.age = age; } //设置工作经历 public void SetWorkExperience(string workDate, string company) { work.WorkDate = workDate; work.Company = company; } //显示 public void Display() { Console.WriteLine("{0} {1} {2}", name, sex, age); Console.WriteLine("工作经历:{0} {1}", work.WorkDate, work.Company); } public Object Clone() { return (Object)this.MemberwiseClone(); } }
//工作经历 class WorkExperience { private string workDate; public string WorkDate { get { return workDate; } set { workDate = value; } } private string company; public string Company { get { return company; } set { company = value; } } }
主函数:
static void Main(string[] args) { Resume a = new Resume("大鸟"); a.SetPersonalInfo("男", "29"); a.SetWorkExperience("1998-2000", "XX公司"); a.Display(); Resume b = (Resume)a.Clone(); b.SetPersonalInfo("女", "123"); b.SetWorkExperience("1998-2006", "YY企业"); a.Display(); b.Display(); Console.Read(); }
在上述例子中,我们创建了一个简历a并设置相关参数,然后对其进行克隆,克隆出来为b
然后通过setPersonalInfo修改了b的姓名和年龄,再通过SetWorkExperience方法去修改其的工作时间和企业名,
最后输出a和b的详细简历。
输出结果如下:
我们发现非引用类型修改后会直接改变其值,a和b之间该部分自个为体,互不干扰
引用类型改变后,所有的克隆对象都会受改变,因为b和a共用一个引用对象(地址),即b将引用对象的值改变了,a也受影响。
深复制:b将a对象中的引用对象也复制过来,不再引用a原有被引用的对象。
深复制代码相比浅复制代码,主要有以下修改:
Resume类中添加了私有构造:
private Resume(WorkExperience work) { this.work = (WorkExperience)work.Clone(); }
Resume类中修改了克隆方法:
public Object Clone() { Resume obj = new Resume(this.work); obj.name = this.name; obj.sex = this.sex; obj.age = this.age; return obj; }
WorkExperience类实现了ICloneable接口,实现了Clone方法:
public Object Clone() { return (Object)this.MemberwiseClone(); }
主函数代码:
static void Main(string[] args) { Resume a = new Resume("大鸟"); a.SetPersonalInfo("男", "29"); a.SetWorkExperience("1998-2000", "XX公司"); Resume b = (Resume)a.Clone(); b.SetPersonalInfo("女", "123"); b.SetWorkExperience("1998-2006", "YY企业"); a.Display(); b.Display(); Console.Read(); }
运行结果:
代码解析:
浅克隆无法让b对象克隆a对象中的对象,那么深克隆应该怎么做呢?自已想一下那不就是让a对象中的对象也实现ICloneable接口就好了?
1.让WorkExperience(工作经历)实现ICloneable接口,可以实现对其的克隆。
2.在Resume中创建克隆该对象中的引用对象的方法(Clone),Clone方法中通过私有构造获取当前对象中引用对象的克隆对象,然后将其相关参数赋值给一个新对象.
3.当代码走完Resume obj = new Resume(this.work);这句话时,obj是null,并不是有值的,接下来的赋值才知给予其内容,这个方法走完才是克隆完成。
4.联想与扩展,这个时候可以想一下dataset中得clone和copy,clone支付制结构,copy赋值结构和内容,就实现了深复制。
- 大话设计模式,让你的代码更完美5---浅复制和深复制
- 大话设计模式,让你的代码更完美4---简单工厂模式和工厂方法模式
- 大话设计模式,让你的代码更完美1---工厂模式
- 大话设计模式,让你的代码更完美2---嵌套装饰模式
- 大话设计模式,让你的代码更完美3---代理模式
- 大话设计模式,让你的代码更完美6---模版方法模式/迪米特
- 大话设计模式,让你的代码更完美7---外观模式
- 大话设计模式,让你的代码更完美8---建造者模式
- 大话设计模式,让你的代码更完美9---旁观者模式
- 大话设计模式,让你的代码更完美10---抽象工厂模式
- 大话设计模式,让你的代码更完美11---状态模式
- 让你快速解开对copy、mutableCopy,深复制和浅复制的疑惑
- 浅复制和深复制的代码实现
- 原型模式浅复制和深复制
- 学习这些设计模式,让你写出更优雅的代码
- java设计模式-原型模式(浅复制,深复制)
- 设计模式学习--原型模式(深复制与浅复制)
- 大话设计模式之原型模式中的复制
- 添加MySQL到VS的C#项目中
- 各种宽度、高度
- Http状态码大全
- ReactNative之helloWorld
- java多线程(一)
- 大话设计模式,让你的代码更完美5---浅复制和深复制
- 今日头条的发家与困局
- Hadoop RCFile存储格式详解(源码分析、代码示例)
- 关于Java异常10件事儿<上>20170510
- xilinx cordic IP核的用法- arctan的算法
- MVC、ThinkPHP、Yii框架、Smarty模板引擎
- 8.变态青蛙跳台阶
- 用Python写FTP客户端程序
- JSP数据交互