Rising Sun

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            148 隨筆 :: 0 文章 :: 22 評論 :: 0 Trackbacks

          淺拷貝就比如像引用類型,而深拷貝就比如值類型。

            淺拷貝是指源對象與拷貝對象共用一份實體,僅僅是引用的變量不同(名稱不同)。對其中任何一個對象的改動都會影響另外一個對象。舉個例子,一個人一開始叫張三,后來改名叫李四了,可是還是同一個人,不管是張三缺胳膊少腿還是李四缺胳膊少腿,都是這個人倒霉。

          深拷貝是指源對象與拷貝對象互相獨立,其中任何一個對象的改動都不會對另外一個對象造成影響。舉個例子,一個人名叫張三,后來用他克隆(假設法律允許)了另外一個人,叫李四,不管是張三缺胳膊少腿還是李四缺胳膊少腿都不會影響另外一個人。比較典型的就是Value(值)對象,如預定義類型Int32Double,以及結(jié)構(gòu)(struct),枚舉(Enum)等。



          C#中有兩種類型變量,一種 是值類型變量,一種是引用類型變量。對于前者,copy是屬于全盤復制;而對于后者,一般的copy只是淺copy,相當于只傳遞一個引用指針一樣。因此 對于后者進行真正copy的時候,也是最費事的,具體的說,必須為其實現(xiàn)ICloneable接口中提供的Clone方法。

          淺拷貝(影子克隆):只復制對象的基本類型,對象類型,仍屬于原來的引用.
          深拷貝(深度克隆):不緊復制對象的基本類,同時也復制原對象中的對象.就是說完全是新對象產(chǎn)生的.

          淺 拷貝和深拷貝之間的區(qū)別:淺拷貝是指將對象中的數(shù)值類型的字段拷貝到新的對象中,而對象中的引用型字段則指復制它的一個引用到目標對象。如果改變目標對象 中引用型字段的值他將反映在原是對象中,也就是說原始對象中對應的字段也會發(fā)生變化。深拷貝與淺拷貝不同的是對于引用的處理,深拷貝將會在新對象中創(chuàng)建一 個新的和原是對象中對應字段相同(內(nèi)容相同)的字段,也就是說這個引用和原是對象的引用是不同的,我們在改變新對象中的這個字段的時候是不會影響到原始對 象中對應字段的內(nèi)容。所以對于原型模式也有不同的兩種處理方法:對象的淺拷貝和深拷貝。

          MemberwiseClone 方法創(chuàng)建一個淺表副本,方法是創(chuàng)建一個新對象,然后將當前對象的非靜態(tài)字段復制到該新對象。如果字段是值類型的,則對該字段執(zhí)行逐位復制。如果字段是引用 類型,則復制引用但不復制引用的對象;因此,原始對象及其復本引用同一對象。深拷貝,即實現(xiàn)ICloneable接口.ICloneable可用于深拷貝 和淺拷貝。拼吾愛
          這些都是概念,但是需要我們理解,下面介紹實例:

          using System;
          using System.Collections.Generic;
          using System.Text;

          namespace WindowsApplication1
          {
          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;  
                            }
            
                      }
           
           
                     
          public class class4
                      
          {
                          
          public static void  Main()
                           
          {
                                      ClassB   sb   
          =   new ClassB();  
                                      sb.Member.Value     
          =   15;  
                                                         
                                      ClassB   nb   
          =   (ClassB)sb.Clone();  
                                      nb.Member.Value     
          =   6;
                                     Console.Write(sb.Member.Value.ToString() 
          + "---" + nb.Member.Value.ToString());                
                                     ClassA nnb 
          = new ClassA();
                                      nnb.Value 
          = 111;
                                     ClassA bbn 
          = new ClassA();
                                     bbn 
          = (ClassA)nnb.Clone();
                                     bbn.Value 
          = 222;
                                     Console.Write(bbn.Value);
                                     Console.Read();

                              }

                      }

          }


          其中.MemberwiseClone()在上面已經(jīng)介紹過了,通過實例可以清楚看到淺拷貝與深拷貝的區(qū)別
          再來個:
          using System;
          using System.Collections.Generic;
          using System.Text;

          namespace WindowsApplication1
          {
              
          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 int aa = 1213;

                      
          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(
          "-------------------------");
                          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;
                      }


                  }


                  
          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.aa 
          = 1111;
                      p.ShowPersonInfo();


                      Console.WriteLine(
          "修改后的淺拷貝對象:");
                      copy.ShowPersonInfo();
                      Console.WriteLine(
          "修改后的深拷貝對象:");
                      dcopy.ShowPersonInfo();

                      Console.WriteLine(
          "直接拷貝對象:");
                      Person PP 
          = p;
                      PP.ShowPersonInfo();

                      Console.ReadLine();


                  }


              }

          }


           
           

          接下來介紹一下數(shù)組的拷貝:
          首先數(shù)組的直接拷貝也就是復制,不用多說看例子:
            int [] numbers = 2345};

             
          int [] numbersCopy = numbers;

          numbersCopy[
          2= 0;

                Console.Write(numbers[
          2]);

                     Console.Write(numbersCopy[
          2]);
          結(jié)果就是

          0

          0

          道理很簡單,數(shù)組的復制也就是引用傳遞,指向的是同一個地址,這不是我們介紹的重點

          接下來

          看一下概念

          數(shù)組是引用類型,所以將一個數(shù)組變量賦予另一個數(shù)組變量,就會得到兩個指向同一數(shù)組的變量。而復制數(shù)組,會使數(shù)組實現(xiàn)ICloneable接口。這個接口定義的Clone()方法會創(chuàng)建數(shù)組的淺副本。

          如果數(shù)組的元素是值類型,就會復制所有的值,如果數(shù)組包含引用類型,則不復制元素,而只復制引用,

          除了使用Clone()方法之外,還可以使用Array.Copy()方法創(chuàng)建淺副本。但Clone()方法和Copy()方法有一個重要區(qū)別:Clone()方法會創(chuàng)建一個新數(shù)組,而Copy()方法只是傳送了階數(shù)相同、有足夠元素空間的已有數(shù)組。

          提示:

          如果需要包含引用類型的數(shù)組的深副本,就必須迭代數(shù)組,創(chuàng)建新對象。

          看一下例子:

          using System;
          using System.Collections.Generic;
          using System.Text;

          namespace WindowsApplication1
          {
              
          class Class2
              
          {
                 
          public static void Main()
                  
          {
                      
          int[] numbers = 2345 };

                      
          int[] numbersCopy = new int[5];

                      numbers.CopyTo(numbersCopy,
          0);

                      numbersCopy[
          2= 0;

                      
          int[] numbers1 = 2345 };

                      
          int[] numbersClone1 = (int[])numbers1.Clone();

                      numbersClone1[
          2= 0;

                      Console.Write(numbers[
          2+ "---" + numbersCopy[2]);

                      Console.Read();


                  }

              }

          }

          我這里介紹的主要是數(shù)組的clone和copyto的用法,兩者都不會改變其中的值,與上面我們的復制有很大的區(qū)別

           

          因為數(shù)組里面是值類型,所以他們不存在引用,而

           class class1
              
          {
                  
          public string aa = "aa";
              }



              
          class class4
              
          {
                  
          public static void Main()
                  
          {
                     
                      class1 aaa 
          = new class1();
                      class1[] array3 
          = new class1[1];
                      class1[] array4 
          = new class1[1];
                      array3[
          0= aaa;
                      
          //Array.Copy(array3, 0, array4, 0,1);
                      array3.CopyTo(array4, 0);
                      
          //array4=(class1[])array3.Clone();
                      array3[0].aa = "bb";

                      Console.Write(array4[
          0].aa);
                      Console.Read();
                  }

              }
          結(jié)果是兩者都改變了值,最后輸出都是bb,那時因為兩者都是淺拷貝,區(qū)別上面已經(jīng)介紹了,所以
          posted on 2013-02-21 11:03 brock 閱讀(234) 評論(0)  編輯  收藏 所屬分類: 學習總結(jié)
          主站蜘蛛池模板: 东至县| 大连市| 凌源市| 平南县| 壤塘县| 金溪县| 监利县| 宝兴县| 苏尼特左旗| 东丽区| 大邑县| 汝城县| 绥阳县| 武胜县| 纳雍县| 枝江市| 淮滨县| 新郑市| 交口县| 加查县| 潮安县| 海阳市| 藁城市| 平果县| 涞源县| 祁阳县| 河东区| 益阳市| 卢龙县| 宁德市| 蓝田县| 建平县| 崇仁县| 姚安县| 元朗区| 包头市| 太原市| 卓资县| 永年县| 无锡市| 汾阳市|