好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

浅复制(Shallow Copy)与深复制(Deep Copy)

浅复制(Shallow Copy)与深复制(Deep Copy)

复制 :对象的复制是生成一个与指定对象完全一样的新对象,实现的方式根据定义可以知道,新建一个类型相同的对象,然后复制原对象的每一个成员和字段。

  浅复制:

     class   Program
    {
          static   void  Main( string  [] args)
        {
            ClassA A  =  new   ClassA();
            CloneObj clone  =  new   CloneObj();
            ClassA newA =  clone.CloneA(A);
        }
    }

      public   class   ClassA
    {
          public  Int32 AValue =  100  ;
    }

      public   class   ClassB
    {
          public  Int32 BValue =  200  ;
    }

      public   class   CloneObj
    {
          public   ClassA CloneA(ClassA obj)
        {
            ClassA newAobj  =  new   ClassA();
            newAobj.AValue  =  obj.AValue;
              return   newAobj;
        }
    } 

上面的CloneObj的CloneA方法就是一个浅复制ClassA对象,修改代码:

     class   Program
    {
          static   void  Main( string  [] args)
        {
            ClassA A  =  new   ClassA();
            CloneObj clone  =  new   CloneObj();
            ClassA newA =  clone.CloneA(A);
        }
    }

      public   class   ClassA
    {
          public  Int32 AValue =  100  ;
          public   ClassB objB;
          public   ClassA()
        {
            objB  =  new   ClassB();
        }
    }

      public   class   ClassB
    {
          public  Int32 BValue =  200  ;
    }

      public   class   CloneObj
    {
          public   ClassA CloneA(ClassA obj)
        {
            ClassA newAobj  =  new   ClassA();
            newAobj.AValue  =  obj.AValue;
            newAobj.objB  =  obj.objB;
              return   newAobj;
        }
    } 

这里ClassA里面包含了引用类型的ClassB对象,这里复制的ClassA对象,如下图:

上面这种方式就是“浅复制(Shallow Copy)”,这里可以在调试时测试下,看看A里面objB的地址和通过复制方法出来的newA的objB的地址:

地址完全一样

浅复制是.NET默认的对象复制方式,Object类提供的Memberwise方法浅复制一个对象。实现深复制,也就是上面的图中,不是共用一个ClassB对象,而是完全创建一个新的ClassB对象。这需要实现ICloneable接口.如下:

 namespace   ConsoleApplication2
{
      class   Program
    {
          static   void  Main( string  [] args)
        {
            ClassA A  =  new   ClassA();
            CloneObj clone = new   CloneObj();
            ClassA newA  =  clone.CloneA(A);

        }
    }

      public   class   ClassA:ICloneable
    {
          public  Int32 AValue =  100  ;
          public   ClassB objB;
          public   ClassA()
        {
            objB  =  new   ClassB();
        }

          object   ICloneable.Clone()
        {
            ClassA objA  =  new   ClassA();
            objA.AValue  =  this  .AValue;
            objA.objB  = ( this .objB  as  ICloneable).Clone()  as   ClassB;
              return   objA;
        }
    }

      public   class   ClassB:ICloneable
    {
          public  Int32 BValue =  200  ;

          object   ICloneable.Clone()
        {
            ClassB objB  =  new   ClassB();
            objB.BValue  =  this  .BValue;
              return   objB;
        }
    }

      public   class   CloneObj
    {
          public   ClassA CloneA(ClassA obj)
        {
              //  ClassA newAobj = new ClassA();
              //  newAobj.AValue = obj.AValue;
              //  newAobj.objB = obj.objB; 
            ClassA newAobj = (obj  as  ICloneable).Clone()  as   ClassA;
              return   newAobj;
        }
    }

} 

测试结果如图:

这里完成了深复制

对象序列化

对象复制比较简单的方式是序列化,将类标记为[Serializable]。对象序列化主要解决的是对象状态的保存问题,这里所说的“对象状态”是指某一时刻对象拥有的字段值的集合。

对象的序列化:将一个内存的对象保存到流中,并在需要时从流中读取数据重建对象的过程称为“对象序列化”和“反序列化”

流:代表一连串有顺序的二进制数据。

利用序列化进行对象的复制——深复制

     [Serializable]
      class   MyClass
    {
          public   int  Index =  1  ;
    }

      class   Program
    {
          static   void  Main( string  [] args)
        {
            MyClass obj  =  new   MyClass();
              //  创建一个内存流对象 
             using  (MemoryStream ms =  new   MemoryStream())
            {
                IFormatter formator  =  new   BinaryFormatter();
                formator.Serialize(ms, obj);    //  将对象序列化到内存流中 

                  //  克隆100个对象 
                 for  ( int  i =  0 ; i <  100 ; i++ )
                {
                    ms.Seek(  0 , SeekOrigin.Begin); //  回到流的开头 
                    obj = (formator.Deserialize(ms)  as  MyClass);  //  反序列化对象 
                    obj.Index += i;    //  设置对象字段 
                    Console.WriteLine( "  对象{0}已创建。  "  , obj.Index);
                }
            }
            Console.ReadKey();
        }
    } 

原理是将对象序列化到流中,然后从流中创建对象(批量),从而实现了深复制。

以上内容整理自《.NET4.0面向对象编程漫谈》作者:金旭亮老师

作者: Gabriel Zhang
出处: http://www.cnblogs.com/mszhangxuefei/
本文版权归作者和博客园共有,欢迎转载,但必须注明出处,并在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

我只有一件事,就是忘记背后,努力面前的,向着标竿直跑

 

分类:  C#.NET点滴

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于浅复制(Shallow Copy)与深复制(Deep Copy)的详细内容...

  阅读:37次