设计模式——浅复制VS深复制
2017-08-20 17:46
281 查看
背景
在学习原型模式的时候,採用了一个差别与其它模式的新方法。採用了“克隆(Clone)方法。通过实现ICloneable接口中的Clone()方法来达到克隆的目的。代码实现过程中,存在了我们所说的浅复制和深复制,以下看看有什么差别。
内容
代码实现
简历浅复制实现:<span style="font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:24px;">using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 浅复制 { class Program { static void Main(string[] args) { Resume a = new Resume("大鸟"); a.SetPersonalInfo("男", "29"); a.SetWorkExperience("1992-2002", "XX公司"); Resume b = (Resume)a.Clone(); b.SetWorkExperience ("1992-2002","YY公司"); Resume c=(Resume )a.Clone (); c.SetPersonalInfo ("男","24"); c.SetWorkExperience ("1995-2200","ZZ企业"); a.Display (); b.Display (); c.Display (); Console .Read (); } } //工作经历类 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; } } } //简历类 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(); } } } </span></span>结果为:
简历深复制实现:
<span style="font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:24px;">//作者:周丽同 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 简历的深复制实现 { class Program { static void Main(string[] args) { Resume a = new Resume("大鸟"); a.SetPersonalInfo("男", "29"); a.SetWorkeExperience("1998-2000", "XX公司"); Resume b = (Resume)a.Clone(); b.SetWorkeExperience("1998-2006", "YY公司"); Resume c = (Resume)a.Clone(); c.SetPersonalInfo("男", "24"); c.SetWorkeExperience("1998-2003", "ZZ企业"); a.Display(); b.Display(); c.Display(); Console.Read(); } } //修改的地方是:让工作经历也实现ICloneable接口 //工作经历类 class WorkExperience:ICloneable { private string workDate; public string WorkDate { get { return workDate; } set { workDate = value; } } private string company; public string Company { get { return company; } set { company = value; } } public Object Clone() { return (Object)this.MemberwiseClone();//“工作经历”类实现克隆方法。 } } //简历类 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(); } private Resume (WorkExperience work) { //提供克隆(Clone)方法调用的私有构造函数,以便克隆“工作经历”的数据; this.work = (WorkExperience)work.Clone(); } //设置个人信息 public void SetPersonalInfo(string sex,string age ) { this.sex = sex; this.age = age; } //设置工作经历 public void SetWorkeExperience(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() { //调用私有的构造函数,让“工作经历”克隆完毕。然后再给这个“简历”对象的相关字段赋值。 //终于返回一个深复制的简历对象。 Resume obj = new Resume(this.work); obj.name = this.name; obj.sex = this.sex; obj.age = this.age; return obj; } } }</span></span>
结果是:
从上面的样例能够看出为什么对于值类型的对象。在克隆的时候能够轻易的复制过来,可是对于引用类型的。在克隆的时候复制过来的仅仅是引用对象,而引用对象的数据是不会复制过来的。这里涉及到了什么是值类型和引用类型。它们在内存中是怎么“走的”。且看且分析:
值类型 | 引用类型 | |
类型 | 结构体;数值类型(整型);浮点型。decimal型;bool型;枚举;可空类型; | 数组。用户定义的类。接口;托付; Object类型;字符串类型; |
能否够包括null值 | 否 | 是 |
内存分配 | 分配在栈中 | 分配在堆中 |
主要职责 | 存储数据 | 传递引用(相当于指针) |
适用场合 | 该类型的共同拥有接口全然由一些数据成员存取属性定义; 永远不可能又子类。 不具有多态行为; | 具有多态行为; 用于定义应用程序的行为; |
浅复制和深复制含义
在这里假设字段是值类型的,则对该字段运行逐位复制,假设字段是引用类型的,则复制引用但不复制引用的对象。对于浅复制和深复制从以下的图来看:浅复制:
深复制:
通过上面的图和代码我们能够知道,能够依据我们的须要进行深复制和浅复制。当须要深复制的时候就须要加上一段对引用对象的深复制(克隆)。我理解深复制,在内存中的走向是:
小结
以上是本人关于c#中浅复制和深复制的一些理解。自己的理解还是有点表面。多多实践样例就会好非常多,望各路大神提出宝贵意见。1、不要害怕自己的想法不正确,对不正确试试就知道了。
2、学会站在巨人的肩膀上。
3、相信自己。
感谢您的宝贵时间~~~
相关文章推荐
- 设计模式——浅复制VS深复制
- 黑马程序员_基础_IO流学习笔记_文本文件读取及复制、字符流的缓冲区和装饰设计模式
- 【设计模式】 模式PK:装饰模式VS适配器模式
- 复制的eclipse常用快捷键 和 设计模式理解方式
- 设计模式笔记——策略模式VS简单工厂模式
- 框架模式VS设计模式
- 【设计模式】简单工厂VS工厂方法
- 设计模式之原型学习 java中的浅复制和深复制
- 设计模式之禅之包装模式群大PK【装饰模式VS适配器模式VS门面模式VS代理模式VS桥梁模式】
- 孙子兵法 VS 设计模式
- 跟我学设计模式视频教程——装饰模式,装饰模式VS代理模式
- 消息发送VS设计模式 C++沉思录的一练习题的另解
- 复制的eclipse常用快捷键 和 设计模式理解方式
- java设计模式---Prototype Pattern---原型模式(复制建立对象)
- Singleton设计模式活学活用: 请求单一 vs 线程单一
- 【设计模式】简单工厂VS工厂方法
- 【设计模式】——原型模式VS模板方法模式
- 软件构架,框架,设计模式.Vs.知识工程
- 【CDP-云设计模式】第4章,4.NFS复制模式(NFS Replica Pattern)
- 设计模式学习笔记九:原型模式(和深浅复制)