萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> asp.net編程 >> 淺談.net平台下深拷貝和淺拷貝

淺談.net平台下深拷貝和淺拷貝

 在.net類庫中,對象克隆廣泛存在於各種類型的實現中,凡是實現了ICloneable接口的類型都具備克隆其對象實例的能力。所以本文講述的深拷貝和淺拷貝也是在實現ICloneable接口的基礎上進行的

基本概念:   淺拷貝:指對象的字段被拷貝,而字段引用的對象不會被拷貝,拷貝對象和原對象僅僅是引用名稱有所不同,但是它們共用一份實體。對任何一個對象的改變,都會影響到另外一個對象。大部分的引用類型,實現的都是淺拷貝,引用類型對象之間的賦值,就是復制一個對象引用地址的副本,而指向的對象實例仍然是同一個。   深拷貝:指對象的子段被拷貝,同時字段引用的對象也進行了拷貝。深拷貝創建的是整個源對象的結構,拷貝對象和原對象相互獨立,不共享任何實例數據,修改一個對象不會影響到另一個對象。值類型之間的賦值操作,執行的就是深拷貝。   基本概念之參考代碼:   代碼如下: class Program     {         static void Main(string[] args)         {             Student s1 = new Student("li", 23);               //淺拷貝             Student s2 = s1;             s2.Age = 27;             s1.ShowInfo();//li's age is 27               //深拷貝             int i = 12;             int j = i;             j = 22;             Console.WriteLine(i);//12               Console.Read();         }     }       class Student     {         public string Name;         public int Age;           public Student(string name, int age)         {             Name = name;             Age = age;         }           public void ShowInfo()         {             Console.WriteLine("{0}'s age is {1}", Name, Age);         }     }     分析:   在上例中,實例s2對s1進行了淺拷貝,對s2中的Age字段進行更改,繼而影響實例s1中的Age字段。   深拷貝中,僅僅是值類型間簡單的賦值,對“j”做出的更改不會更改“i”的值。   深淺拷貝的實現: 代碼如下: public object Clone() { return this.MemberwiseClone(); }     MemberwiseClone:創建一個淺表副本。過程是創建一個新對象,然後將當前對象的非靜態字段復制到該新對象。如果字段是值類型,則對該字段執行逐位復制,如果字段是引用類型,則復制引用但不復制引用對象。   參考代碼:    代碼如下: class Program     {         static void Main(string[] args)         {             ClassA ca = new ClassA();             ca.value = 88;             ClassA ca2 = new ClassA();             ca2 = (ClassA)ca.Clone();             ca2.value = 99;             Console.WriteLine(ca.value + "-----" + ca2.value);//88---99               ClassB cb = new ClassB();             cb.Member.value = 13;               ClassB cb2 = (ClassB)cb.Clone();             cb2.Member.value = 7;             Console.WriteLine(cb.Member.value.ToString() + "------" + cb2.Member.value.ToString());//淺拷貝:7---7      深拷貝:13----7                          Console.Read();         }     }       public class ClassA : ICloneable     {         public int value = 0;           public object Clone()         {             return this.MemberwiseClone();         }     }       public class ClassB : ICloneable     {         public ClassA Member = new ClassA();           public object Clone()         {              //淺拷貝             return this.MemberwiseClone();               //深拷貝             ClassB obj = new ClassB();             obj.Member = (ClassA)Member.Clone();             return obj;         }     }       分析:   上例中,ca2復制ca對象,實現了深度拷貝。結果如同代碼中顯示:ca2中值類型字段的改變並不影響ca中的字段。   在類ClassB中,引用類型成員Member,如果用ClassA中的clone方法實現則僅僅實現的是淺拷貝,在上述參考代碼中能夠看出:對cb2的member的改變影響著cb。但是當使用參考代碼中的深度拷貝後,對cb2的member的改變則不會影響著cb。   在網上找到一個綜合的例子,有對比的來進行解釋深淺拷貝:   實例1:   代碼如下: public class Sex:ICloneable      {         private string _PSex;         public string PSex         {             set{ _PSex = value;}             get { return _PSex; }         }           //public object Clone()         //{         //    return this.MemberwiseClone();         //}     }       public class Person : ICloneable     {           private Sex sex = new Sex();         public int aa = 3;           public string pSex         {             set { sex.PSex = value; }             get { return sex.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("-------------------------");             Console.WriteLine(this.aa);         }         //淺拷貝         public object Clone()         {             return this.MemberwiseClone();         }         //深拷貝         public object DeepClone()         {             Person newP = new Person();             newP.PName = this._PName;             newP.pSex = this.pSex;             return newP;         }     } &nbs
copyright © 萬盛學電腦網 all rights reserved