C# 对象深拷贝、浅铐贝、直接拷贝(转)
生活随笔
收集整理的這篇文章主要介紹了
C# 对象深拷贝、浅铐贝、直接拷贝(转)
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
C#中有兩種類型變量,一種是值類型變量,一種是引用類型變量。對(duì)于前者,copy是屬于全盤復(fù)制;而對(duì)于后者,一般的copy只是淺copy,相當(dāng)于只傳遞一個(gè)引用指針一樣。因此對(duì)于后者進(jìn)行真正copy的時(shí)候,也是最費(fèi)事的,具體的說(shuō),必須為其實(shí)現(xiàn)ICloneable接口中提供的Clone方法。
???? 淺拷貝(影子克隆):只復(fù)制對(duì)象的基本類型,對(duì)象類型,仍屬于原來(lái)的引用.
?????深拷貝(深度克隆):不緊復(fù)制對(duì)象的基本類,同時(shí)也復(fù)制原對(duì)象中的對(duì)象.就是說(shuō)完全是新對(duì)象產(chǎn)生的.
淺拷貝和深拷貝之間的區(qū)別:淺拷貝是指將對(duì)象中的數(shù)值類型的字段拷貝到新的對(duì)象中,而對(duì)象中的引用型字段則指復(fù)制它的一個(gè)引用到目標(biāo)對(duì)象。如果改變目標(biāo)對(duì)象中引用型字段的值他將反映在原是對(duì)象中,也就是說(shuō)原始對(duì)象中對(duì)應(yīng)的字段也會(huì)發(fā)生變化。深拷貝與淺拷貝不同的是對(duì)于引用的處理,深拷貝將會(huì)在新對(duì)象中創(chuàng)建一個(gè)新的和原是對(duì)象中對(duì)應(yīng)字段相同(內(nèi)容相同)的字段,也就是說(shuō)這個(gè)引用和原是對(duì)象的引用是不同的,我們?cè)诟淖冃聦?duì)象中的這個(gè)字段的時(shí)候是不會(huì)影響到原始對(duì)象中對(duì)應(yīng)字段的內(nèi)容。所以對(duì)于原型模式也有不同的兩種處理方法:對(duì)象的淺拷貝和深拷貝。
???? MemberwiseClone 方法創(chuàng)建一個(gè)淺表副本,方法是創(chuàng)建一個(gè)新對(duì)象,然后將當(dāng)前對(duì)象的非靜態(tài)字段復(fù)制到該新對(duì)象。如果字段是值類型的,則對(duì)該字段執(zhí)行逐位復(fù)制。如果字段是引用類型,則復(fù)制引用但不復(fù)制引用的對(duì)象;因此,原始對(duì)象及其復(fù)本引用同一對(duì)象。深拷貝,即實(shí)現(xiàn)ICloneable接口.ICloneable可用于深拷貝和淺拷貝。?
????示例代碼如下:
????? C# 示例Code
class?Program
????{
????????public?class?Sex
????????{
????????????private?string?_PSex;
????????????public?string?PSex
????????????{
????????????????set
????????????????{
????????????????????_PSex?=?value;
????????????????}
????????????????get
????????????????{
????????????????????return?_PSex;
????????????????}
????????????}
?
????????}
????????public?class?Person?:?ICloneable
????????{
????????????private?Sex?_pSex?=?new?Sex();
????????????public?string?pSex
????????????{
????????????????set
????????????????{
????????????????????_pSex.PSex?=?value;
????????????????}
????????????????get
????????????????{
????????????????????return?_pSex.PSex;
????????????????}
????????????}
????????????private?string?_PName;
????????????public?string?PName
????????????{
????????????????set
????????????????{
????????????????????this._PName?=?value;
????????????????}
????????????????get
????????????????{
????????????????????return?this._PName;
????????????????}
????????????}
????????????public?void?ShowPersonInfo()
????????????{
????????????????Console.WriteLine("-------------------------");
????????????????Console.WriteLine("Name:{0}?Sex:{1}",?_PName,this?.pSex?);
????????????????Console.WriteLine("-------------------------");
????????????}
????????????//淺拷貝
????????????public?object?Clone()
????????????{
????????????????return?this.MemberwiseClone();
????????????}
????????????//深拷貝
????????????public?object?DeepClone()
????????????{
????????????????Person?newP?=?new?Person();
????????????????newP.PName?=?this._PName;
????????????????newP.pSex?=?this.pSex?;
????????????????return?newP;
????????????}
????????}
????????static?void?Main(string[]?args)
????????{
????????????Console.WriteLine("原對(duì)象:");
????????????Person?p?=?new?Person();
????????????p.PName?=?"JackLee";
????????????p.pSex?=?"男";
????????????p.ShowPersonInfo();
????????????//淺拷貝????????
????????????Person?copy?=?(Person)p.Clone();
????????????//深拷貝
????????????Person?dcopy?=?(Person)p.DeepClone();
????????????Console.WriteLine("修改后的原對(duì)象:");
????????????p.PName?=?"JackZhao";
????????????p.pSex?=?"女";
????????????p.ShowPersonInfo();
????????????Console.WriteLine("修改后的淺拷貝對(duì)象:");
????????????copy.ShowPersonInfo();
????????????Console.WriteLine("修改后的深拷貝對(duì)象:");
????????????dcopy.ShowPersonInfo();
????????????Console.WriteLine("直接拷貝對(duì)象:");
????????????Person?PP?=?p;
????????????PP.ShowPersonInfo();
????????????
????????????Console.ReadLine();
????????}
???????
????}
????運(yùn)行結(jié)果如下:
??????
????說(shuō)明:當(dāng)然對(duì)于深拷貝還可以有其它的實(shí)現(xiàn),比如說(shuō)用序列化的方法等等。
????在JavaScript中的也有對(duì)象的淺拷貝與深拷貝,看下面的例子:
???? JavaScript中的示例代碼Code
<!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.0?Transitional//EN">
<HTML>
<HEAD>
<TITLE>?New?Document?</TITLE>
</HEAD>
<BODY>
<SCRIPT?LANGUAGE="JavaScript">
<!--
function?Object.prototype.clone(){
????var?newObj?=?new?Object();
????for(elements?in?this){
????????newObj[elements]?=?this[elements];
????}
????return?newObj;
}
function?Object.prototype.cloneAll(){
????function?clonePrototype(){}
????clonePrototype.prototype?=?this;
????var?obj?=?new?clonePrototype();
????for(var?ele?in?obj){
????????if(typeof(obj[ele])=="object")?obj[ele]?=?obj[ele].cloneAll();
????}
????return?obj;
}
????var?obj1????????????=?new?Object();
????obj1.Team????????????=?"First";
????obj1.Powers????????????=?new?Array("Iori","Kyo");
????obj1.msg????????????=?function(){alert()};
????obj1.winner????????????=?new?Object();
????obj1.winner.name????=?obj1.Powers[0];
????obj1.winner.age????????=?23;
????obj1.winner.from????=?"Japan"
????var?obj1_clone????????????=?obj1.cloneAll();
????obj1_clone.Team????????????=?"Second";
????obj1_clone.Powers????????=?new?Array("Jimmy","Anndy");
????obj1_clone.winner.name????=?obj1_clone.Powers[1];
????obj1_clone.winner.age????=?22;
????obj1_clone.winner.from????=?"USA";
????msg??=?"2003界拳皇單打獨(dú)斗杯,拳皇挑戰(zhàn)賽:??\n\n???A組?對(duì)戰(zhàn)形式:\n\n"
????msg?+=?obj1.Team+"?組?,人員名單:"+obj1.Powers+"\n";
????msg?+=?"第一輪過(guò)后,勝利者為:"+obj1.winner.name?+"?,參賽者年齡:"+obj1.winner.age+"?,來(lái)自島國(guó):?"+obj1.winner.from+"\n";
????msg?+=?"\n\n???B組?對(duì)戰(zhàn)形式:\n\n"
????msg?+=?obj1_clone.Team+"?組?,人員名單:"+obj1_clone.Powers+"\n";
????msg?+=?"第一輪過(guò)后,勝利者為:"+obj1_clone.winner.name?+"?,參賽者年齡:"+obj1_clone.winner.age+"?,來(lái)自國(guó)際警察部隊(duì):?"+obj1_clone.winner.from+"\n";
????alert(msg);
//-->
</SCRIPT>
</BODY>
</HTML>
???? 淺拷貝(影子克隆):只復(fù)制對(duì)象的基本類型,對(duì)象類型,仍屬于原來(lái)的引用.
?????深拷貝(深度克隆):不緊復(fù)制對(duì)象的基本類,同時(shí)也復(fù)制原對(duì)象中的對(duì)象.就是說(shuō)完全是新對(duì)象產(chǎn)生的.
淺拷貝和深拷貝之間的區(qū)別:淺拷貝是指將對(duì)象中的數(shù)值類型的字段拷貝到新的對(duì)象中,而對(duì)象中的引用型字段則指復(fù)制它的一個(gè)引用到目標(biāo)對(duì)象。如果改變目標(biāo)對(duì)象中引用型字段的值他將反映在原是對(duì)象中,也就是說(shuō)原始對(duì)象中對(duì)應(yīng)的字段也會(huì)發(fā)生變化。深拷貝與淺拷貝不同的是對(duì)于引用的處理,深拷貝將會(huì)在新對(duì)象中創(chuàng)建一個(gè)新的和原是對(duì)象中對(duì)應(yīng)字段相同(內(nèi)容相同)的字段,也就是說(shuō)這個(gè)引用和原是對(duì)象的引用是不同的,我們?cè)诟淖冃聦?duì)象中的這個(gè)字段的時(shí)候是不會(huì)影響到原始對(duì)象中對(duì)應(yīng)字段的內(nèi)容。所以對(duì)于原型模式也有不同的兩種處理方法:對(duì)象的淺拷貝和深拷貝。
???? MemberwiseClone 方法創(chuàng)建一個(gè)淺表副本,方法是創(chuàng)建一個(gè)新對(duì)象,然后將當(dāng)前對(duì)象的非靜態(tài)字段復(fù)制到該新對(duì)象。如果字段是值類型的,則對(duì)該字段執(zhí)行逐位復(fù)制。如果字段是引用類型,則復(fù)制引用但不復(fù)制引用的對(duì)象;因此,原始對(duì)象及其復(fù)本引用同一對(duì)象。深拷貝,即實(shí)現(xiàn)ICloneable接口.ICloneable可用于深拷貝和淺拷貝。?
????示例代碼如下:
????? C# 示例Code
class?Program
????{
????????public?class?Sex
????????{
????????????private?string?_PSex;
????????????public?string?PSex
????????????{
????????????????set
????????????????{
????????????????????_PSex?=?value;
????????????????}
????????????????get
????????????????{
????????????????????return?_PSex;
????????????????}
????????????}
?
????????}
????????public?class?Person?:?ICloneable
????????{
????????????private?Sex?_pSex?=?new?Sex();
????????????public?string?pSex
????????????{
????????????????set
????????????????{
????????????????????_pSex.PSex?=?value;
????????????????}
????????????????get
????????????????{
????????????????????return?_pSex.PSex;
????????????????}
????????????}
????????????private?string?_PName;
????????????public?string?PName
????????????{
????????????????set
????????????????{
????????????????????this._PName?=?value;
????????????????}
????????????????get
????????????????{
????????????????????return?this._PName;
????????????????}
????????????}
????????????public?void?ShowPersonInfo()
????????????{
????????????????Console.WriteLine("-------------------------");
????????????????Console.WriteLine("Name:{0}?Sex:{1}",?_PName,this?.pSex?);
????????????????Console.WriteLine("-------------------------");
????????????}
????????????//淺拷貝
????????????public?object?Clone()
????????????{
????????????????return?this.MemberwiseClone();
????????????}
????????????//深拷貝
????????????public?object?DeepClone()
????????????{
????????????????Person?newP?=?new?Person();
????????????????newP.PName?=?this._PName;
????????????????newP.pSex?=?this.pSex?;
????????????????return?newP;
????????????}
????????}
????????static?void?Main(string[]?args)
????????{
????????????Console.WriteLine("原對(duì)象:");
????????????Person?p?=?new?Person();
????????????p.PName?=?"JackLee";
????????????p.pSex?=?"男";
????????????p.ShowPersonInfo();
????????????//淺拷貝????????
????????????Person?copy?=?(Person)p.Clone();
????????????//深拷貝
????????????Person?dcopy?=?(Person)p.DeepClone();
????????????Console.WriteLine("修改后的原對(duì)象:");
????????????p.PName?=?"JackZhao";
????????????p.pSex?=?"女";
????????????p.ShowPersonInfo();
????????????Console.WriteLine("修改后的淺拷貝對(duì)象:");
????????????copy.ShowPersonInfo();
????????????Console.WriteLine("修改后的深拷貝對(duì)象:");
????????????dcopy.ShowPersonInfo();
????????????Console.WriteLine("直接拷貝對(duì)象:");
????????????Person?PP?=?p;
????????????PP.ShowPersonInfo();
????????????
????????????Console.ReadLine();
????????}
???????
????}
????運(yùn)行結(jié)果如下:
??????
????說(shuō)明:當(dāng)然對(duì)于深拷貝還可以有其它的實(shí)現(xiàn),比如說(shuō)用序列化的方法等等。
????在JavaScript中的也有對(duì)象的淺拷貝與深拷貝,看下面的例子:
???? JavaScript中的示例代碼Code
<!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.0?Transitional//EN">
<HTML>
<HEAD>
<TITLE>?New?Document?</TITLE>
</HEAD>
<BODY>
<SCRIPT?LANGUAGE="JavaScript">
<!--
function?Object.prototype.clone(){
????var?newObj?=?new?Object();
????for(elements?in?this){
????????newObj[elements]?=?this[elements];
????}
????return?newObj;
}
function?Object.prototype.cloneAll(){
????function?clonePrototype(){}
????clonePrototype.prototype?=?this;
????var?obj?=?new?clonePrototype();
????for(var?ele?in?obj){
????????if(typeof(obj[ele])=="object")?obj[ele]?=?obj[ele].cloneAll();
????}
????return?obj;
}
????var?obj1????????????=?new?Object();
????obj1.Team????????????=?"First";
????obj1.Powers????????????=?new?Array("Iori","Kyo");
????obj1.msg????????????=?function(){alert()};
????obj1.winner????????????=?new?Object();
????obj1.winner.name????=?obj1.Powers[0];
????obj1.winner.age????????=?23;
????obj1.winner.from????=?"Japan"
????var?obj1_clone????????????=?obj1.cloneAll();
????obj1_clone.Team????????????=?"Second";
????obj1_clone.Powers????????=?new?Array("Jimmy","Anndy");
????obj1_clone.winner.name????=?obj1_clone.Powers[1];
????obj1_clone.winner.age????=?22;
????obj1_clone.winner.from????=?"USA";
????msg??=?"2003界拳皇單打獨(dú)斗杯,拳皇挑戰(zhàn)賽:??\n\n???A組?對(duì)戰(zhàn)形式:\n\n"
????msg?+=?obj1.Team+"?組?,人員名單:"+obj1.Powers+"\n";
????msg?+=?"第一輪過(guò)后,勝利者為:"+obj1.winner.name?+"?,參賽者年齡:"+obj1.winner.age+"?,來(lái)自島國(guó):?"+obj1.winner.from+"\n";
????msg?+=?"\n\n???B組?對(duì)戰(zhàn)形式:\n\n"
????msg?+=?obj1_clone.Team+"?組?,人員名單:"+obj1_clone.Powers+"\n";
????msg?+=?"第一輪過(guò)后,勝利者為:"+obj1_clone.winner.name?+"?,參賽者年齡:"+obj1_clone.winner.age+"?,來(lái)自國(guó)際警察部隊(duì):?"+obj1_clone.winner.from+"\n";
????alert(msg);
//-->
</SCRIPT>
</BODY>
</HTML>
轉(zhuǎn)載于:https://www.cnblogs.com/chy8219/archive/2008/02/28/1085428.html
總結(jié)
以上是生活随笔為你收集整理的C# 对象深拷贝、浅铐贝、直接拷贝(转)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【转载】split / break po
- 下一篇: SharePoint Conferenc