C# 对象深拷贝、浅铐贝、直接拷贝(转)
生活随笔
收集整理的這篇文章主要介紹了
C# 对象深拷贝、浅铐贝、直接拷贝(转)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
C#中有兩種類型變量,一種是值類型變量,一種是引用類型變量。對于前者,copy是屬于全盤復制;而對于后者,一般的copy只是淺copy,相當于只傳遞一個引用指針一樣。因此對于后者進行真正copy的時候,也是最費事的,具體的說,必須為其實現ICloneable接口中提供的Clone方法。
???? 淺拷貝(影子克隆):只復制對象的基本類型,對象類型,仍屬于原來的引用.
?????深拷貝(深度克隆):不緊復制對象的基本類,同時也復制原對象中的對象.就是說完全是新對象產生的.
淺拷貝和深拷貝之間的區別:淺拷貝是指將對象中的數值類型的字段拷貝到新的對象中,而對象中的引用型字段則指復制它的一個引用到目標對象。如果改變目標對象中引用型字段的值他將反映在原是對象中,也就是說原始對象中對應的字段也會發生變化。深拷貝與淺拷貝不同的是對于引用的處理,深拷貝將會在新對象中創建一個新的和原是對象中對應字段相同(內容相同)的字段,也就是說這個引用和原是對象的引用是不同的,我們在改變新對象中的這個字段的時候是不會影響到原始對象中對應字段的內容。所以對于原型模式也有不同的兩種處理方法:對象的淺拷貝和深拷貝。
???? MemberwiseClone 方法創建一個淺表副本,方法是創建一個新對象,然后將當前對象的非靜態字段復制到該新對象。如果字段是值類型的,則對該字段執行逐位復制。如果字段是引用類型,則復制引用但不復制引用的對象;因此,原始對象及其復本引用同一對象。深拷貝,即實現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("原對象:");
????????????Person?p?=?new?Person();
????????????p.PName?=?"JackLee";
????????????p.pSex?=?"男";
????????????p.ShowPersonInfo();
????????????//淺拷貝????????
????????????Person?copy?=?(Person)p.Clone();
????????????//深拷貝
????????????Person?dcopy?=?(Person)p.DeepClone();
????????????Console.WriteLine("修改后的原對象:");
????????????p.PName?=?"JackZhao";
????????????p.pSex?=?"女";
????????????p.ShowPersonInfo();
????????????Console.WriteLine("修改后的淺拷貝對象:");
????????????copy.ShowPersonInfo();
????????????Console.WriteLine("修改后的深拷貝對象:");
????????????dcopy.ShowPersonInfo();
????????????Console.WriteLine("直接拷貝對象:");
????????????Person?PP?=?p;
????????????PP.ShowPersonInfo();
????????????
????????????Console.ReadLine();
????????}
???????
????}
????運行結果如下:
??????
????說明:當然對于深拷貝還可以有其它的實現,比如說用序列化的方法等等。
????在JavaScript中的也有對象的淺拷貝與深拷貝,看下面的例子:
???? 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界拳皇單打獨斗杯,拳皇挑戰賽:??\n\n???A組?對戰形式:\n\n"
????msg?+=?obj1.Team+"?組?,人員名單:"+obj1.Powers+"\n";
????msg?+=?"第一輪過后,勝利者為:"+obj1.winner.name?+"?,參賽者年齡:"+obj1.winner.age+"?,來自島國:?"+obj1.winner.from+"\n";
????msg?+=?"\n\n???B組?對戰形式:\n\n"
????msg?+=?obj1_clone.Team+"?組?,人員名單:"+obj1_clone.Powers+"\n";
????msg?+=?"第一輪過后,勝利者為:"+obj1_clone.winner.name?+"?,參賽者年齡:"+obj1_clone.winner.age+"?,來自國際警察部隊:?"+obj1_clone.winner.from+"\n";
????alert(msg);
//-->
</SCRIPT>
</BODY>
</HTML>
???? 淺拷貝(影子克隆):只復制對象的基本類型,對象類型,仍屬于原來的引用.
?????深拷貝(深度克隆):不緊復制對象的基本類,同時也復制原對象中的對象.就是說完全是新對象產生的.
淺拷貝和深拷貝之間的區別:淺拷貝是指將對象中的數值類型的字段拷貝到新的對象中,而對象中的引用型字段則指復制它的一個引用到目標對象。如果改變目標對象中引用型字段的值他將反映在原是對象中,也就是說原始對象中對應的字段也會發生變化。深拷貝與淺拷貝不同的是對于引用的處理,深拷貝將會在新對象中創建一個新的和原是對象中對應字段相同(內容相同)的字段,也就是說這個引用和原是對象的引用是不同的,我們在改變新對象中的這個字段的時候是不會影響到原始對象中對應字段的內容。所以對于原型模式也有不同的兩種處理方法:對象的淺拷貝和深拷貝。
???? MemberwiseClone 方法創建一個淺表副本,方法是創建一個新對象,然后將當前對象的非靜態字段復制到該新對象。如果字段是值類型的,則對該字段執行逐位復制。如果字段是引用類型,則復制引用但不復制引用的對象;因此,原始對象及其復本引用同一對象。深拷貝,即實現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("原對象:");
????????????Person?p?=?new?Person();
????????????p.PName?=?"JackLee";
????????????p.pSex?=?"男";
????????????p.ShowPersonInfo();
????????????//淺拷貝????????
????????????Person?copy?=?(Person)p.Clone();
????????????//深拷貝
????????????Person?dcopy?=?(Person)p.DeepClone();
????????????Console.WriteLine("修改后的原對象:");
????????????p.PName?=?"JackZhao";
????????????p.pSex?=?"女";
????????????p.ShowPersonInfo();
????????????Console.WriteLine("修改后的淺拷貝對象:");
????????????copy.ShowPersonInfo();
????????????Console.WriteLine("修改后的深拷貝對象:");
????????????dcopy.ShowPersonInfo();
????????????Console.WriteLine("直接拷貝對象:");
????????????Person?PP?=?p;
????????????PP.ShowPersonInfo();
????????????
????????????Console.ReadLine();
????????}
???????
????}
????運行結果如下:
??????
????說明:當然對于深拷貝還可以有其它的實現,比如說用序列化的方法等等。
????在JavaScript中的也有對象的淺拷貝與深拷貝,看下面的例子:
???? 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界拳皇單打獨斗杯,拳皇挑戰賽:??\n\n???A組?對戰形式:\n\n"
????msg?+=?obj1.Team+"?組?,人員名單:"+obj1.Powers+"\n";
????msg?+=?"第一輪過后,勝利者為:"+obj1.winner.name?+"?,參賽者年齡:"+obj1.winner.age+"?,來自島國:?"+obj1.winner.from+"\n";
????msg?+=?"\n\n???B組?對戰形式:\n\n"
????msg?+=?obj1_clone.Team+"?組?,人員名單:"+obj1_clone.Powers+"\n";
????msg?+=?"第一輪過后,勝利者為:"+obj1_clone.winner.name?+"?,參賽者年齡:"+obj1_clone.winner.age+"?,來自國際警察部隊:?"+obj1_clone.winner.from+"\n";
????alert(msg);
//-->
</SCRIPT>
</BODY>
</HTML>
轉載于:https://www.cnblogs.com/chy8219/archive/2008/02/28/1085428.html
總結
以上是生活随笔為你收集整理的C# 对象深拷贝、浅铐贝、直接拷贝(转)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【转载】split / break po
- 下一篇: SharePoint Conferenc