浅谈对对象clone的理解

对象clone是一非常方便且有用的方法,在对数据的处理,尤其是大数据量的处理时,更觉可贵。

现谈下本人对对象clone的理解。

 

CLONE分为两种:深度clone(deep clone) 和 浅度clone(shallow clone). 都是 创建一与原对象具有相同类型的新实例。

但是有区别的,其创建过程不完全相同:

浅度clone(shallow clone): 创建与原始对象具有相同类型的新实例,然后复制原始对象的非静态字段(静态字段不属于类实例)。

     如果字段是值类型的,则对该字段 执行逐位复制。如果字段是引用类型,则复制该引用但不复制被引用的对象。

深度clone(deep clone): 创建与原始对象具有相同类型的新实例,然后复制原始对象的非静态字段(静态字段不属于类实例)。

     如果字段是值类型的,则对该字段 执行逐位复制。如果字段是引用类型,则复制该引用指向的实例而非复制该引用。

 

注意以上着为橙色的字体,区别就在此。可见,

相同点: clone所得对象与原对象的reference是不同的(因为不是一个实例),Equals的结果是false的(前提是没有override object's   Equals方法)。

区别: shallow clone的对象,其2级/3级/../n级引用对象的reference是相同的(因为是复制的reference,都指向同一实例),所以Equals(前提是没有override object's Equals方法)其对象关系网中的引用对象,是true的。

而deep clone的对象,是递归复制其对象关系网中的对象实例(而非引用),则Equals肯定是false的。

注意点: 无论deep or shallow clone,其进行的都是复制,而非new工作,所以类的初始化过程在clone中是不会产生的,即:成员初始化、类初始化等等,它仅是对已有对象的一个copy的,并将copy所得对象的heap address 赋值给新的reference的。

 

DEMO之:有对象X,A,B,C,X引用了A、B,A引用了C,伪代码演示如下:

shallow clone

 

deep clone

 

.NET中,Object默认所带的protected MemberwiseClone()方法,就是一个 shallow clone,要实现deep clone,

则要自己来实现的。.NET提供了一个接口IClone,是用来支持对象的deep clone的,但归根接底,还是要我们自己来实现clone()方法的,也就是说,实现该方法的不一定就是deep clone,甚至都不是clone,要看你是如何实现的,它仅是一个约束,要求你应该去这么做,但你不这么做,它也没办法(不过你不这么做,也只会给自己在使用中带来麻烦的)。

比如:我们看下.NET自己所实现IClone的几个类:Array 和 ArrayList,前者是shallow clone,后者则是deep clone的。

Array.Clone

 

ArrayList.Clone

 

这里提供一个利用序列化进行deep clone方法的实现(前提,对象关系网中的对象必须是可序列化Serializable的)

Serializable deep clone

 

posted @ 2008-07-30 07:34  FallingAutumn  阅读(608)  评论(0编辑  收藏  举报