登陆注册
8183300000132

第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);}

}

}

}

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

    三维动画审美谈

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

    云计算和现代远程教育

    本书介绍了云计算知识、云计算的特性、云计算技术、云计算中的访问云、云计算中的云存储、云计算在远程教育中的应用等内容。
  • 下一代互联网

    下一代互联网

    本书系统介绍了下一代互联网的进展情况,包括下一代互联网的概念解析,国内外下一代互联网的最新发展情况,下一代互联网的关键技术进展,以及各国发展下一代互联网的政策计划。最后分析了下一代互联网对未来社会的影响,提出我国发展下一代互联网的政策建议等。全书共6章,包括互联网发展历史和现状,下一代互联网基本概念,下一代互联网研究最新进展,下一代互联网发展现状,我国发展下一代互联网现状,发展下一代互联网战略建议。
  • 科学伴你行-神奇的通信技术

    科学伴你行-神奇的通信技术

    在日常生活中,有时人们要借助于小旗子来进行通信联络,比如,开运动会时,发令员常常要用小旗子与计时员联系;当你乘坐火车进入车站时,都会看到车站工作人员拿着红色和绿色的小旗子在站台上进行指挥;在战争中,打出白色旗子表示投降,插上红色旗子表明胜利;航行在茫茫大海上的船只,双方船员会凭不同旗帜组成的标志,来了解对方的意思。以上种种用小旗子来“说话”的通信方式就叫做旗语。
  • 智能计算方法概论

    智能计算方法概论

    本书以智能计算领域的若干前沿技术为主线,内容包括数字水印技术在版权保护区和身份认证中的应用,量子算法在信号处理、图像处理中的应用,量子数据挖掘技术,小波方法在医学图像处理中的应用等。
热门推荐
  • 重生后细作王妃要改邪归正

    重生后细作王妃要改邪归正

    传闻镇南王暴戾残忍,视人命如草芥,权势滔天,闻者胆战心惊。宁流莺被护在狐裘大衣之中,一边还由着镇南王小心翼翼的喂着热乎乎的豆沙包,她眨眨眼,看着那剑眉星目满是宠溺温柔。传闻啊,总是不可信的。
  • 君临天下妖妃太毒辣

    君临天下妖妃太毒辣

    21世纪,007最后说了一句话;7号再见了无人得知007口中的7号是谁东羽国右丞相无子,膝下仅三位女儿。大小姐林采欣京城四美之一,国色天香。二小姐林贝欣且也是碧月羞花而嫡三小姐林妖妩名气却比丞相府的小姐任何一个都大。原因便是这三小姐聪明伶俐,古灵精怪,虽说才学不咱地,但就是能圣宠不衰啊!林妖妩与东羽公主轩辕萝姐妹相称林妖妩与东羽大子轩辕澈青梅竹马,且有定亲之说,但是半个月前轩辕澈随林妖妩称游山她没能保护好太子,致使轩辕太子坠崖—摔残了双腿于是轩辕皇帝盛怒之下欲将林妖妩问斩,却不想北越国来话了,要求东羽国将右丞相府嫡小姐以质子之名送与北越六年却无人知道人那娇小的身体下早已换了一个灵魂
  • 爱像北风吹

    爱像北风吹

    如果有一天我爱上了一个男人,那是不是意味着我错了,张以杨这样问自己,他不知道该如何面对自己的亲人,兄弟,朋友,本以为孤独可以换来安心,但是却换不来一句安慰,人活着不是人累了,大部分的时候是心累了。可是,我还是相信有人能够感知。
  • 我的名字叫王村

    我的名字叫王村

    在一个线性时间的来龙去脉中,范小青以中庸的力度打开了两个世界:一个是哲学,一个是现实。极简的故事主题:我丢失了弟弟,我又去寻找弟弟。故事叙述中,患有智障的弟弟恰如龙卷风,把所有人物都裹挟了进去。丰富庞杂的情节,循环往复的纠结,谵妄无休的盘诘,把故事的迷径写得海咸河淡,温度适中。独到的以萤火之光起笔,以一片废墟灰烬收山,显示出作家卓越丰稔的艺术功力。
  • 穿越万界之命运卡牌

    穿越万界之命运卡牌

    自从陌熙被一个来自宇宙之外的系统坑了后,陌熙为了活下来,为了世界的和平,开始了他穿越万界等价贩卖的生活。“别跑啊,萧炎是吧,住手,别打我啊,想不想挽回你的尊严呢?我这里有张等级卡,一次可以跳五星哦,只要两年寿命就可获得”“柯南,你想恢复工藤新一,那你没看错,我这里就有张恢复卡,只要十年寿命你就可以获得,要不要来一张呢?”“鼬,你别拿这种仇恨的眼神看着我啊,只要你族人的十双眼睛,你就能获得另一双万花筒哦”......陌熙“艾玛,这些人怎么都那么倔呢”表示很无奈。 (重点!非完全系统文,系统文,文!!!)
  • 冰山王爷的融化剂

    冰山王爷的融化剂

    “相亲记,奇穿越,神秘仙翁赠玉佩,是偶然,还是命定?遇到他,展笑颜,泪轻落,一点一点消融;倾全心,爱难舍,一丝一丝心痛,花落花开开不休,上善若水水自流,红颜远,相思苦,几番意,唯有尝过爱之真谛才会深得体会。女主的命运如何?请期待”冰山王爷的融化剂”冷酷王爷如何化冷酷变柔情,倾尽一生只为红颜,宁可负天下,绝不负卿!不知情之所起,一往而情深!
  • 封神奇闻

    封神奇闻

    神秘的封神学院专为培养神而存在。天命少年,怀揣着成神的梦想,被命运裹挟前行。当他终于成神的时候,才知道这一切并不是结束,而是另一个开始。
  • 原来是喜欢吖

    原来是喜欢吖

    十七岁那年,他告诉她:“满目山河,既往不咎。”却不曾想,“书书,请你告诉我‘你是年少的欢喜’,下一句是什么?”你还是你,但当年的少年却还是你吗?
  • 洛家嫡女的小狼狗夫君

    洛家嫡女的小狼狗夫君

    洛宛言身为全律所年纪最轻的金牌律师,现代黄金鉴渣师,怎么也没想到自己居然有一天会因为渣男前任的前女友泼的一杯咖啡而触电身亡,从一个走上人生巅峰的金牌律师变成了一个古代人——还是胎穿。便宜爹是江南首富,便宜娘是侯府千金,爹疼娘宠,自己是钱眼子里掉出来的金凤凰,洛宛言顿时重拾人生希望,开始了古代渣女的开疆扩土之路。
  • 乘仙归去

    乘仙归去

    来无声去无踪,人称我为无影。但我来时声势浩大,所向披靡!去时惊天动地,神哭鬼号,只是人们习惯地称呼我为无常罢了。没错,我就是世事中的无常,人们口中的玄妙,天地间的浩然正气,宇宙里的无穷无极。我就是天道!天道正是在下!