背景

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

    StringBuilder拼接小技巧 Stopwatch watch = new Stopwatch(); watch.Start(); var sb = new StringBuilder(); ; ...

  2. 使用vim进行java编程

    首先:编写源代码Test.java 1class Test{                                                                       ...

  3. linux缺页异常处理--内核空间【转】

    转自:http://blog.csdn.net/vanbreaker/article/details/7867720 版权声明:本文为博主原创文章,未经博主允许不得转载. 缺页异常被触发通常有两种情况 ...

  4. laravel中建立公共视图的方法

    1.用法概要 @include('common.header') 包含子视图 @extends('article.common.base') 继承基础模板 @yield('content') 视图占位 ...

  5. nginx安全日志分析脚本的编写

    https://blog.csdn.net/nextdoor6/article/details/51914966

  6. 日志三剑客ELK

    新的服务器需要搭建ELK三剑客,就是日志分析的工具,整理下步骤,供以后复习用. 说明下,我这里使用的是logstash从redis里获取日志信息的.所以还需要redis,这里就不做redis的介绍了. ...

  7. 牛客网 暑期ACM多校训练营(第一场)J.Different Integers-区间两侧不同数字的个数-离线树状数组 or 可持久化线段树(主席树)

    J.Different Integers 题意就是给你l,r,问你在区间两侧的[1,l]和[r,n]中,不同数的个数. 两种思路: 1.将数组长度扩大两倍,for(int i=n+1;i<=2* ...

  8. UVA 437 巴比伦塔 【DAG上DP/LIS变形】

    [链接]:https://cn.vjudge.net/problem/UVA-437 [题意]:给你n个立方体,让你以长宽为底,一个个搭起来(下面的立方体的长和宽必须大于上面的长和宽)求能得到的最长高 ...

  9. [COCI2015]JABUKE

    题目大意: 一个$n\times m(n,m\leq500)$的网格图中有若干个标记点,有$q(q\leq10^5)$个操作,每次新加入一个标记点,并询问和新加入点最近的点的距离. 思路: 记录对于每 ...

  10. Java this关键字详解

    this 关键字用来表示当前对象本身,或当前类的一个实例,通过 this 可以调用本对象的所有方法和属性.例如: public class Demo{ public int x = 10; publi ...