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

來源:互聯網
上載者:User

 在.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;        }    }     class Program    {        static void Main(string[] args)        {            Console.WriteLine("原對象:");            Person p = new Person();            p.PName = "Lee";            p.pSex = "男";             p.ShowPersonInfo();//原對象:lee 男 3             //淺拷貝                    Person copy = (Person)p.Clone();            //深拷貝            Person dcopy = (Person)p.DeepClone();             Console.WriteLine("修改後的原對象:");            p.PName = "Zhao";            p.pSex = "女";            p.aa = 1;            p.ShowPersonInfo();//zhao 女 1             Console.WriteLine("修改後的淺拷貝對象:");            copy.ShowPersonInfo();//lee 女 3             Console.WriteLine("修改後的深拷貝對象:");            dcopy.ShowPersonInfo();//lee 男 3             Console.WriteLine("直接拷貝對象:");            Person PP = p;            PP.ShowPersonInfo();//zhao 女 1             Console.ReadLine();        }    }   分析: 首先需指出,上例中在類Sex中,加入Clone方法和不加對執行個體中運算結果沒有影響。 類Person中,參考型別但卻是string類型的PName欄位,參考型別pSex欄位,實值型別aa。 初始值:lee 男 3  (先進行深淺拷貝) 修改值:zhao 女 1 淺拷貝值:lee 女 3 深拷貝值:lee 男 3 直接拷貝值:趙 女 1 結果:上述可以說是對深淺拷貝中經常遇到的幾種類型做出總結和對比,相信在一番體悟後可以學到一些知識。 執行個體2:  代碼如下:class Program    {        static void Main(string[] args)        {            int[] numbers = { 2, 3, 4, 5 };            int[] numbersCopy = new int[5];            numbers.CopyTo(numbersCopy, 0);            numbersCopy[2] = 0;             int[] numbers1 = { 2, 3, 4, 5 };            int[] numbersClone1 = (int[])numbers1.Clone();            numbersClone1[2] = 0;             Console.Write(numbers[2] + "---" + numbersCopy[2]);//4---0            Console.Write(numbers1[2] + "---" + numbersClone1[2]);//4--0              //數組的複製也就是引用傳遞,指向的是同一個地址            int[] numbers2 = { 2, 3, 4, 5 };            int[] numbers2Copy = numbers2;            numbers2Copy[2] = 0;             Console.Write(numbers2[2]);//0            Console.Write(numbers2Copy[2]);//0             Console.Read();        }    }  暫不做分析,認真領悟。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.