克隆-浅表副本与深层副本

克隆
当将一个引用变量赋值绐另外一个引用变量时,只是简单地创建了指向同一个对象的第二个引用。如果要制造一个对象的副本,你就需要某种机制来创建同一个类的新实例,并且基于原来对象的状态初始化该实例。Object.MemberwiseClone方法就是做这件事情的;然而,它不是一个公有办法。更进一步说,如果对象要想支持克隆( cloning),往往需要实现System.ICloneable接口,该接口有一个方法Clone:
namespace System {
public  interface ICloneable
{
Object Clone() ;
}

MemberwiseClone方法执行的是浅表副本(shallow copy),这意味着它只是将原对象的每个字段的值拷贝到克隆体中。如果字段是一个对象引用,那么,拷贝的仅仅是这个引用.而不是引用的对象。下面的类使用 浅表副本 实现了ICloneable接口:
Pulic sealed class Marriage:System.ICloneable{
Internal Person g;
Internal Person b;

Public Object Clone(){
Return this.MemberwiseClone();
}
}

图5.9是浅表副本的结果。




深层副本 (deep copy)是指递归拷贝其字段所引用的所有对象,如图5.10所示。深层副本经常是人们所期望的;但它不是默认的行为,并且在一般情形下实现深层副本也不是好主意。深层副本除了会引起额外的内存活动和资源消耗之外,当对象层次结构( a graph of objects)出现环路时,深层副本还会出现问题,其原因是递归有可能陷入无限循环。不过,对于简单的对象层次结构,它全少是可以实现的,如下例5.8所示。

示例5.8 实现System.ICloneable接口
Public sealed class Marriage:System.ICloneable{
Internal Person g;
Internal Person b;
Public Object Clone(){
//首先进行浅拷贝
Marriage result=(Marriage)this.MemberwiseClone();
//深拷贝每个字段
Result.g=(Person){this.g.Clone()};
Result.b=(Person){this.b.Clone()};
Return result;
}
}

在示例5.8中,Clone的实现居然可以不调用MemberwisClone方法。一个可供选择的实现就是简单地使用new操作符实例化第二个对象,并且手动产生它的字段。此外你还可以定义一个私有构造函数,使这两个部分(实例化和初始化)合并成一步。示例5.9就是这样一种实现。

示例5.9  使用关键字new实现System.ICloneable接口
Public sealed class Marriage:System.ICloneable{
Internal Person g;
Internal Person b;

Private Marriage(Person g,Person b){
This.g=(Person)g.Clone();
This.b=(Person)b.Clone();
}

Public Object Clone(){
Return new Marriage(g,b)
}
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值