浅复制(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://HdhCmsTestcnblogs测试数据/mszhangxuefei/
本文版权归作者和博客园共有,欢迎转载,但必须注明出处,并在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
我只有一件事,就是忘记背后,努力面前的,向着标竿直跑
分类: C#.NET点滴
作者: Leo_wl
出处: http://HdhCmsTestcnblogs测试数据/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息查看更多关于浅复制(Shallow Copy)与深复制(Deep Copy)的详细内容...