登陆注册
15296300000132

第132章 9 克隆对象分为浅拷贝和深拷贝

小A:“克隆对象有哪些?”

大B:“克隆对象分为浅拷贝和深拷贝。我给你详细讲一下。浅拷贝就是克隆的对象和它的源对象共享引用的对象,举个例子,可能不恰当,假设牛肉刀削面引用一个对象:Money,表示它值多少钱,这里说的对象是说它是System。Object继承的(c#),也就是说不同的浅拷贝对象,他们的价钱是一样的,当克隆对象的价钱变过之后,它所引用的对象的价钱也就随之改变了,比如面馆。调低了牛肉刀削面的价格,由5块钱调到了4块钱,那么每碗面的价格都变到了4块钱。但对值类型而言,每个浅拷贝对象都有自己的拷贝,也就是说,当改变克隆对象的值类型时,它的源对象相应属性不会改变。深拷贝就是完全的拷贝。不仅值类型有自己的拷贝,连引用对象也有自己的一份拷贝,修改克隆对象的任何属性,也不会对源对象产生任何影响。原型管理器,就是提供原型注册使用,当创建对象使,可以使用里面的对象进行克隆,当有新的实例对象时,也可以将他们加到原型管理器里。说的有点乱,程序员,还是用代码交流最好。”

下面的程序分别实现了原型克隆时浅拷贝和深拷贝。

//

//理解深拷贝和浅拷贝

//

//浅表副本创建与原始对象具有相同类型的新实例,然后复制原始对象的非静态字段。

//如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制该

//引用但不复制被引用的对象;这样,原始对象中的引用和复本中的引用指向同一个对象。

//相反,对象的深层副本复制对象中字段直接或间接引用的全部内容。

//

//例如,如果X 是一个具有对对象A 和对象B 的引用的Object,并且对象A 还具

//有对对象M 的引用,则X 的浅表副本是对象Y,而Y 同样具有对对象A 和对象。

//的引用。相反,X 的深层副本是对象Y,而对象Y 具有对对象C 和对象D 的直接引

//用以及对对象N 的间接引用,其中C 是A 的副本,D 是B 的副本,而N 是M 的副本。

using System;

using System。Collections;

using System。IO;

using System。Runtime。Serialization。Formatters。Binary;

using System。Runtime。Serialization;

using System。Data;

namespace Prototype

{

///《summary》

///Prototype类型实例

///《/summary》

class TestPrototypeApp

{

///《summary》

///应用程序的主入口点。

///《/summary》

[STAThread]

static void Main(string[]args)

{

//定义原型管理器

NoodleManager noodleManager=new NoodleManager();

//客户要求下面三碗面

Noodle beefNoodle=(Noodle)noodleManager[“牛肉拉面”]。Clone();

//Noodle beefNoodle=(Noodle)noodleManager[“牛肉拉面”]。DeepClone();

Noodle muttonNoodle=(Noodle)noodleManager[“羊肉拉面”]。Clone();

Noodle beefCutNoodle=(Noodle)noodleManager[“牛肉刀削面”]。Clone();

//修改克隆对象中的引用对象的属性,验证它是浅拷贝还是深拷贝

beefNoodle。TbName=,“哈哈哈!克隆对象改名了,你改不改”;

//显示原始对象的NoodelName和TbName?

Console。WriteLine(noodleManager[“牛肉拉面”]。NoodleName noodleManager[“牛肉拉面”]。TbName “\n”);

//显示克隆对象的NoodleName和。

Console。WriteLine(beefNoodle。NoodleName beefNoodle。TbName “\n”);

//将新的产品加入原型管理器,以备以后克隆时使用,下面是定义了一种新的面条-羊肉刀削面,

//并把它添加到面条管理器中,如果以后再有客户点这个面,直接克隆即可。

noodleManager[“羊肉刀削面”]=new CutNoodle(“羊肉刀削面”);

//克隆一碗羊肉刀削面

Noodle muttonCutNoodle=(Noodle)noodleManager[“羊肉刀削面”]。Clone();

Console。WriteLine(noodleManager[“羊肉刀削面”]。NoodleName “\n”);

Console。WriteLine(muttonCutNoodle。NoodleName “\n”);

Console。ReadLine();

}

}

//抽象产品-面条

//序列化属性,为深拷贝时使用,每个派生类都要加上此属性才能实现深拷贝

[Serializable]

public abstract class Noodle

{

//定义一个DataTable对象,主要是为了验证对比类中含有引用对象时的深拷贝和浅拷贝时的不同,

//你也可以采用别的任何引用对象

protected DataTable dataTable=new DataTable();

public string TbName

{

get{return dataTable。TableName;}

set{dataTable。TableName=value;}

}

//字段

protected string noodleName;

//特性

public string NoodleName

{

get{return noodleName;}

set{noodleName=value;}

}

public abstract Noodle Make(string name);

//浅克隆的接口

public abstract Noodle Clone();

//深克隆的接口

public abstract Noodle DeepClone();

}

//具体产品,拉面

[Serializable]

public class PullNoodle:Noodle

{

public PullNoodle(string name)

{

this。NoodleName=name;

this。TbName=name “table”;

Console。WriteLine(“PullNoodle is made\n”);

}

//实现浅拷贝

public override Noodle Clone()

{

return(Noodle)this。MemberwiseClone();

}

//实现深拷贝,“淹咸菜”的过程,先将对象序列化到内存流,再反序列化,即可得到深克隆

public override Noodle DeepClone()

{

//定义内存流

MemoryStream ms=new MemoryStream();

//定义二进制流

IFormatter bf=new BinaryFormatter();

//序列化

bf。Serialize(ms,this);

//重置指针到起始位置,以备反序列化

ms。Position=0;

//返回反序列化的深克隆对象

return(Noodle)bf。Deserialize(ms);

}

public override Noodle Make(string name)

{

return new PullNoodle(name);

}

}

//具体产品-刀削面

[Serializable]

public class CutNoodle:Noodle

{

public CutNoodle(string name)

{

this。NoodleName=name;

this。TbName=name “table”;

Console。WriteLine(“CutNoodle is made\n”);

}

//实现浅克隆

public override Noodle Clone()

{

return(Noodle)this。MemberwiseClone();

}

public override Noodle Make(string name)

{

return new CutNoodle(name);

}

//实现深克隆

public override Noodle DeepClone()

{

MemoryStream ms=new MemoryStream();

IFormatter bf=new BinaryFormatter();

bf。Serialize(ms,this);

ms。Position=0;

return(Noodle)bf。Deserialize(ms);

}

}

//定义原型管理器,用于存储原型集合,这里采用的是。

class NoodleManager

{

//定义。

protected Hashtable noodleHt=new Hashtable();

protected Noodle noodle;

public NoodleManager()

{

//初始化时加入三种基本原型

noodle=new PullNoodle(“牛肉拉面”);

noodleHt。Add(“牛肉拉面”,noodle);

noodle=new PullNoodle(“羊肉拉面”);

noodleHt。Add(“羊肉拉面”,noodle);

noodle=new CutNoodle(“牛肉刀削面”);

noodleHt。Add(“牛肉刀削面”,noodle);

}

//索引器,用于添加,访问Noodle对象

public Noodle this[string key]

{

get{return(Noodle)noodleHt[key];}

set{noodleHt。Add(key,value);}

}

}

}

同类推荐
  • 三维动画审美谈

    三维动画审美谈

    数字时代,美的标准充满更多的不确定性。而三维动画以数字图像形式成为这个图时代的代表。三维动画及三维图像不仅仅是由于应用了仿真数字图像技术而带来的虚拟空间,还有更多的是由三维图像技术所引发或引导的被扩展的图像技术,这些技术无不应用在现代视觉设计领域的各个方面,并且,由此引起社会的追热,引起审美观念的改变。这些改变是在进行中的,变化中的,也是在发展中的。对于未知的美,我们做的只是追寻和记录,我们不知道以后的美将会是什么样,尽管我们苦苦追寻,孜孜探讨,同时也在默默审视。我们在追寻中享受美,在探讨中认知美,在审视中体验美……
  • 黑客就在你身边

    黑客就在你身边

    互联网络正在改变着我们的生活,每个人都处在互联网的天罗地网之中。本书以轻松的笔调,向人们介绍了有关“黑客”的知识。当你读完这本书后,你会发觉“黑客”一点都不神秘,他们渴望全社会对他们有一个公正的评价。
  • 条形码技术与应用

    条形码技术与应用

    条形码是一种可供电子仪器自动识别的标准符号,是由一组黑白相间、粗细不同的条、空符号按一定编码规则排列组成的标记,用以表示一定的信息,确认某个物体或规定它的移动,能正确快速地为产、供、销各环节在采集、处理和交换信息时提供标识。
  • 计算机与人工智能(科学新知丛书)

    计算机与人工智能(科学新知丛书)

    本书是专门为中小学生编写的科普读物。全书共分八个部分,分别就计算机诞生的历程,计算机的种类、构造、作用及其发展趋势等方面进行了详尽的论述,全书论述深入浅出,行文活泼流畅。为本书的主要读者——广大的中小学生朋友认识计算机、了解计算机和掌握计算机提供了一把钥匙,是新时期中小学生开展素质教育不可多得的科普读物,中小学生家长及教师阅读此书也能从中获得有益的启示和感悟。
  • 组建家庭局域网与无线网

    组建家庭局域网与无线网

    该书是“快乐驿站”丛书之一,是一本精心为初级家庭电脑用户打造的局域网与无线网组建入门与提高的图书,同时还涉及一些办公网络的组建内容。《组建家庭局域网与无线网》以局域网和无线网的功能、设置以及实际应用为导向,用生动的实例、形象的图解和幽默的语言循序渐进地介绍了局域网和无线网的概念、产品、设计、组建、调试与维护的相关内容。
热门推荐
  • 王爷要点脸

    王爷要点脸

    她是华夏第一医药世家的继承人,也是见过无数杀掠的军医,却在一天面临了双重打击,她见到自己心爱的男人有了未婚夫,她在那天死于亲人手中……老天不负她,居然让她在另一世界重生了!废材?什么?姐姐打得你哭爹喊娘!不过这只忠犬似的某王,当初是不是不该救他?
  • 网游之弹痕

    网游之弹痕

    叶落成功转职为一名狙击手,潜伏于黑暗,越级杀BOSS,凭借先天优势,踏上热血争霸之途,纵横游戏世界,众美环绕!
  • 始毒之祖

    始毒之祖

    自古以来,有仙,有道,有魔,始毒之祖,以大毅力,通达天路,开创世界。飘飘乎,一剑天外。毒染满天。
  • 最爱是你:S级特工组

    最爱是你:S级特工组

    风云雨,二十一世纪云天高中冷面校草一枚,学习成绩优异,家庭条件优良,车祸,本以为再也无法相见的两个人竟重新相遇!只是再次遇见,他却已经不记得她了。“你不记得我?没关系,我记得你就行啦!”“你不爱我了?没关系,只要我还爱你,就一定不会放弃!”看二十一世纪美少女千寒,穿越未知时空,重续前世恋情!与时空强者强强联手!
  • 错踏星云暮

    错踏星云暮

    她,不过一世花妖。他,不过一世灵猫。她的轮回三世不过是命运的捉弄。他的守护三世不过是心酸的体现。错弄的缘分,只是悲剧。
  • 午夜摸鬼人

    午夜摸鬼人

    鬼能摸人,人也能摸鬼,而我就是那个午夜摸鬼人。夜深,月黑风高,独坐坟尖。虽然张着眼睛,却什么也看不见。一只冰凉的小手交到我手里,沿着小手向上摸去,纤柔细腻的手臂。少女天生的羞涩,使她微微轻颤,向后退去。我下意识地抬手向上,想要摸一摸她的小脸,却只碰到了一截血肉粘稠的脖颈断茬。她没有头…………
  • 倾城“男”妃带虫逃

    倾城“男”妃带虫逃

    穿越了,好吧,随遇而安!穿越成妃,更好,有吃有喝!穿越成‘男妃’,最好,不仅有吃有喝还不用担心陪睡!某女窃喜!但是肚中有种,谁可以告诉她,娃子他爸是谁?既然没人认领,担心被宰的她只有跑路了。但是他为啥子会生出一条虫子呢?!
  • 木罗泪

    木罗泪

    木系的落败,源于谁?木系的兴起,终于谁?木罗站在山顶俯视,这里将是木系的天下,谁也夺不走。木罗握了握手中的流石,这既是五界中争夺的法宝,那好,木罗就将那流石一扔,谁能够拥有流石之人,就可以来云木殿来找木罗大帝了。俯首一笑,这天下又该如何?五界之争重起,流石再起,风波不断。木罗一战,成而天下,败于情谊。
  • 极品鹿鼎记

    极品鹿鼎记

    不一样的鹿鼎记,不一样的韦小宝......
  • 逐鹿问鼎记

    逐鹿问鼎记

    醒掌天下权,醉卧美人膝!当朱自明踏足鹿鼎,这个世界,历史的走向悄然发生偏移!一只蝴蝶,要如何煽动一阵风暴!且看朱自明,一步一步,逐鹿江湖,问鼎天下!