程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#讀書筆記----淺度復制與深度復制

C#讀書筆記----淺度復制與深度復制

編輯:C#入門知識

前提條件:從 一個變量到另一個變量按值復制對象,而不是按引用復制對象(即以與結構相同的方式復制)可能非常復雜。因為一個對象可能包含許多對象的引用,例如字段、成 員等,這將涉及許多煩人的處理操作。把每個成員從一個對象復制到另一個對象中可能不會成功,因為其中一些成員可能是引用類型。

淺復制:簡單地按照成員復制對象可以通過派生於System.Object的MemberwiseClone()方法來完成,這是一個受保護的方法,但是很容易在對象上定義一個調用該方法的公共方法。這個方法的復制功能成為淺復制。

淺復制的好處:不用引用對象類型。

淺復制的方法:


view sourceprint?01 using System; 

02 using System.Collections.Generic; 

03 using System.Text; 

04   

05 namespace ConsoleApplication2 

06 { 

07     public class Content 

08     { 

09         public int Val; 

10     } 

11   

12     public class Cloner 

13     { 

14         public Content MyContent = new Content(); 

15         public Cloner(int newVal) 

16         { 

17             MyContent.Val = newVal; 

18         } 

19         public object GetCopy() 

20         { 

21             return MemberwiseClone(); 

22         } 

23     } 

24   

25     public class Program 

26     { 

27         static void Main(string[] args) 

28         { 

29             Cloner mySource = new Cloner(5); 

30             Cloner myTarget = (Cloner)mySource.GetCopy(); 

31             Console.WriteLine("MyTarget.MyContent.val = {0}",myTarget.MyContent.Val); 

32             mySource.MyContent.Val = 2; 

33             Console.WriteLine("MyTarget.MyContent.val = {0}", myTarget.MyContent.Val); 

34             Console.ReadKey(); 

35         } 

36     } 

37 }


這裡的mySource.MyContent.Val = 2改變了該公共字段val的值,所以導致了生成結果如下:MyTarget.MyContent.val = 5MyTarget.MyContent.val = 2上面通過復制引用類型來體現了淺度復制的使用方法。如果想要使生成的值都為5,就需要使用深度復制.
關於深度復制:

使用深度復制,必須使類實現ICloneable接口,該接口有一個方法Clone(),這個方法不帶參數,返回一個對象類型, 其簽名和上面使用的GetCopy()方法相同。 1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4  5 namespace ConsoleApplication2 6 { 7     public class Content 8     { 9         public int Val;10 11     }12 13     public class Cloner:ICloneable14     {15         public Content MyContent = new Content();16 17         public Cloner(int newVal)18         {19             MyContent.Val = newVal;20         }21         public object GetCopy()22         {23             return MemberwiseClone();24         }25 26         #region ICloneable 成員27 28         public object Clone()29         {30             Cloner clonedCloner = new Cloner(MyContent.Val);31             return clonedCloner;32         }33 34         #endregion35     }36 37     public class Program38     {39         static void Main(string[] args)40         {41             Cloner mySource = new Cloner(5);42             Cloner myTarget = (Cloner)mySource.Clone();43             Console.WriteLine("MyTarget.MyContent.val = {0}",myTarget.MyContent.Val);44             mySource.MyContent.Val = 2;45             Console.WriteLine("MyTarget.MyContent.val = {0}", myTarget.MyContent.Val);46             Console.ReadKey();47         }48     }49 }


因為在將Cloner實現ICloneable時使用了深度復制,來創建了作為當前實例(這裡指clonedCloner)副本的新對象,
最後在測試深度復制時,又調用了Clone()的方法,而沒有調用GetCopy()方法,所以導致了myTarget.MyContent.Val的值一直是new Cloner(5),而不是在最後定義的值2.
經過這個知識點的學習,我認為ICloneable()接口的存在就是為了調用clone()方法的,如果需要將某個引用類型或者值類型的值直接復制給對象,
就直接讓其實現該接口的方法,這個可能理解的不正確,希望大家和我交流。

關於ICloneable()接口的Clone()方法的說明:
Clone 既可作為深層副本實現,也可作為淺表副本實現。在深層副本中,所有的對象都是重復的;而在淺表副本中,只有頂級對象是重復的,並且頂級以下的對象包含引用。

結果克隆必須與原始實例具有相同的類型或是原始實例的兼容類型。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved