浅谈对对象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,伪代码演示如下:

ContractedBlock.gif ExpandedBlockStart.gif shallow clone
= X.shallowClone();
X.Equals(Y) 
== FALSE;
X.A.Equals(Y.A) 
== TRUE;
X.B.Equals(Y.B) 
== TRUE;
X.A.C.Equals(Y.A.C) 
== TRUE;

 

ContractedBlock.gif ExpandedBlockStart.gif deep clone
= X.deepClone();
X.Equals(Y) 
== FALSE;
X.A.Equals(Y.A) 
== FALSE;
X.B.Equals(Y.B) 
== FALSE;
X.A.C.Equals(Y.A.C) 
== FALSE;

 

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

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

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

ContractedBlock.gif ExpandedBlockStart.gif Array.Clone
public object Clone()
{
    
return base.MemberwiseClone();
}

 

 
public object Clone()
{
    
return base.MemberwiseClone();
}

 

ContractedBlock.gif ExpandedBlockStart.gif ArrayList.Clone
public virtual object Clone()
{
    ArrayList list 
= new ArrayList(this._size);
    list._size 
= this._size;
    list._version 
= this._version;
    Array.Copy(
this._items, 0, list._items, 0this._size);
    
return list;
}

 

 

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

ContractedBlock.gif ExpandedBlockStart.gif Serializable deep clone
        public Object DeepClone()
        {    
            
if (null == thisreturn null;
            
using (MemoryStream stream = new MemoryStream())
            {
                BinaryFormatter formatter 
= new BinaryFormatter();
                formatter.Serialize(stream,
this);
                stream.Position 
= 0;
                
return formatter.Deserialize(stream);
            }
        }

 

转载于:https://www.cnblogs.com/FallingAutumn/archive/2008/07/30/1256052.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值