背景

在学习原型模式的时候,採用了一个差别与其它模式的新方法。採用了“克隆(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>

结果为:

           

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

简历深复制实现:

<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值

内存分配

分配在栈中

分配在堆中

主要职责

存储数据

传递引用(相当于指针)

适用场合

该类型的共同拥有接口全然由一些数据成员存取属性定义;

永远不可能又子类。

不具有多态行为;

具有多态行为;

用于定义应用程序的行为;

浅复制和深复制含义

在这里假设字段是值类型的,则对该字段运行逐位复制,假设字段是引用类型的,则复制引用但不复制引用的对象。对于浅复制和深复制从以下的图来看:

浅复制:

深复制:

通过上面的图和代码我们能够知道,能够依据我们的须要进行深复制和浅复制。当须要深复制的时候就须要加上一段对引用对象的深复制(克隆)。我理解深复制,在内存中的走向是: 

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" style="font-size:18px; font-family:KaiTi_GB2312; text-align:center">

小结

   以上是本人关于c#中浅复制和深复制的一些理解。自己的理解还是有点表面。多多实践样例就会好非常多,望各路大神提出宝贵意见。
1、不要害怕自己的想法不正确,对不正确试试就知道了。

2、学会站在巨人的肩膀上。
3、相信自己。


感谢您的宝贵时间~~~

设计模式——浅复制VS深复制的更多相关文章

  1. 设计模式-原型模式(Prototype)【重点:浅复制与深复制】

    讲故事 最近重温了一下星爷的<唐伯虎点秋香>,依然让我捧腹不已,幻想着要是我也能有一名秋香如此的侍女,夫复何求呀,带着这个美好的幻想沉沉睡去... 突然想到,我是一名程序猿呀,想要什么对象 ...

  2. iOS 浅复制和深复制的深层理解,含示例

    转载:https://www.zybuluo.com/MicroCai/note/50592 版权归 @MicroCai 所有 以下是正文: 浅复制就是指针拷贝:深复制就是内容拷贝. 集合的浅复制 ( ...

  3. java基础-浅复制与深复制的理解

    浅复制与深复制在很多编程语言中都有出现,那么什么是浅复制,什么是深复制呢? 要区分浅复制与深复制,首先我们要明确什么是复制,怎样才算是复制.复制的例子在生活中也随处可见,如复印一份文档,复制一段文字等 ...

  4. iOS 浅复制、深复制、完全复制的知识点梳理验证(附加归档解档)

    在之前转载的一片文章中,文中对浅复制和深复制进行了详细的解读,同时还提到了深复制(one-level-deep copy).完全复制(true copy)的概念,并指出iOS开发中的深复制是单层深赋值 ...

  5. 深度解析javascript中的浅复制和深复制

    原文:深度解析javascript中的浅复制和深复制 在谈javascript的浅复制和深复制之前,我们有必要在来讨论下js的数据类型.我们都知道有Number,Boolean,String,Null ...

  6. JAVA中浅复制与深复制 - coolmist - ITeye技术网站

    body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...

  7. Java中引用的浅复制和深复制

    Java中除了基本类型int,char,double等的赋值是按照值传递之外,其余的类型和对象都是按照引用进行传递的. 下面来看一个关于引用的例子. package referenceCopy;// ...

  8. js中的浅复制和深复制

    浅复制:浅复制是复制引用,复制后的引用都是指向同一个对象的实例,彼此之间的操作会互相影响 深复制:深复制不是简单的复制引用,而是在堆中重新分配内存,并且把源对象实例的所有属性都进行新建复制,以保证深复 ...

  9. 也来谈一谈js的浅复制和深复制

    1.浅复制VS深复制 本文中的复制也可以称为拷贝,在本文中认为复制和拷贝是相同的意思.另外,本文只讨论js中复杂数据类型的复制问题(Object,Array等),不讨论基本数据类型(null,unde ...

随机推荐

  1. 寻找道路(NOIP2014)神奇之题。。

    原题传送门 这道题嘛.. 首先根据题目,我们要先知道哪些点能够到达终点.(反向BFS) 然后我们再求最短路的途中,必须随时判断周围的点是否被第一次BFS标记过.. 所以再来一次BFS. 数组记得清零, ...

  2. 请求路径@PathVariable与请求参数@RequestParam的区别

    转自:http://www.iteye.com/problems/101566: http://localhost:8080/Springmvc/user/page.do?pageSize=3& ...

  3. jQuery的动画方法

    /* animate参数: 参数一:要改变的样式属性值,写成字典的形式 参数二:动画持续的时间,单位为毫秒,一般不写单位 参数三:动画曲线,默认为‘swing’,缓冲运动,还可以设置为‘linear’ ...

  4. cmake add_executable 与 include_directories

    在cmake里add_executable里如果没有包含.cpp文件,该.cpp文件就不适用include_directories包含文件

  5. C# web server的开发流程

    http://blog.csdn.net/h0322/article/details/4776819

  6. CF986A Fair【图论/BFS】

    [题意]: 有些公司将在Byteland举办公平的会议.Byteland的n个城镇,m条两镇之间的双向道路.当然,你可以使用道路从任一个城镇到达任何城镇. 有k种商品产自Byteland,并且每个城镇 ...

  7. Apache优化建议

    Apache是Web服务器软件,它最常见是搭配PHP开发语言去使用.今天,小编根据Apache官方手册再结合实际,整理出下面这些优化建议,希望对大家的Apache服务器的运行效率有效果. 1.控制Ma ...

  8. c++ —— .bat 对拍

    #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #i ...

  9. [NOIP模拟赛][贪心]奶牛晒衣服.

    奶牛晒衣服(dry) [问题描述] 在熊大妈英明的带领下,时针和它的同伴生下了许多牛宝宝.熊大妈决定给每个宝宝都穿上可爱的婴儿装.于是,为牛宝宝洗晒衣服就成了很不爽的事情. 圣人王担负起了这个重任.洗 ...

  10. How to: Launch the Debugger Automatically

    Sometimes, you may need to debug the startup code for an application that is launched by another pro ...