对象“浅复制”与“深复制”的区别
对于只包含简单字段的对象而言,对象复制的过程可以简化为“新建一个同类型的对象,然后逐个复制字段值“的过程la
例如一下代码定义一个类ClassA
class ClassA
{
public int AValue = 100;
}
以下方法可完成复制ClassA对象的任务
public static ClassA CloneObject(ClassA obj)
{
ClassA newObj = new ClassA();
newObj.AValue = obj.AValue; //字段复制
return newObj;
}
static void Main(string[] args)
{
ClassA ObjA = new ClassA();
ClassA other = CloneObject(ObjA); //将ClassA对象复制一份
}
整个对象复制过程可以用图形表示
对象之间是可以享福组合的,如果我们考虑到对象组合的情况,对象复制的额问题就变得复杂起来了。
public class ClassA
{
public int i = 100;
public ClassB EnbedObject; //ClassA包含一个ClassB的对象
public ClassA()
{
EnbedObject = new ClassB(); //创建被包含对象
}
}
class ClassB
{
public int BValue = 200;
}
基于”通过字段值复制实现对象复制“的原则
static ClassA CloneObject(ClassA obj)
{
ClassA newObj = new ClassA();
newObj.AValue = obj.AValue; //字段复制
newObj.EnbedObject = obj.EnbedObject; //引用复制
return obj;
}
以下是ClassA对象复制的示例代码
ClassA ObjA = new ClassA();
ClassA other = CloneObject(ObjA); //将ClassA对象复制一份
由于类ClassA中字段 EmbedObject是 一个引用类型的变量,所有仅仅将字段值复制一下,带来的结果是老对象和新对象”公用 “一个Class对象
]
上图的对象复制方式为”浅复制“
上图的对象复制方式为”深复制“,其特点是连包含的对象也一并复制
编程实现”深复制“
浅复制是.NET Framework默认的对象复制方式,Object类提供一个Memberwise方法浅复制一个对象。为了实现深复制,.NET FrameWork提供一个ICloneable接口,要求采用”深复制“方式进行对象复制的类必须实现此接口:
public interface ICloneable
{
object Clone();
}
class ClassA : ICloneable
{
public int AValue = 100;
public ClassB EmbedObject; //ClassA包含一个ClassB对象
object ICloneable.Clone()
{
ClassA ObjA = new ClassA();
ObjA.AValue = this.AValue;
ObjA.EnbedObject = (this.EnbedObject as ICloneable).Clone() as ClassB;
return ObjA;
}
}
class ClassB:ICloneable
{
public int BValue = 200;
object ICloneable.Clone()
{
ClassB ObjB = new ClassB();
ObjB.BValue = this.BValue;
return ObjB;
}
}
类ClassA和类ClassB都实现了ICloneable接口。ClassA对象的Clone方法在内部调用它所包含ClassB对象的Clone方法完成ClassB对象的复制工作。