用户操作
[留言]  [发消息]  [加为好友] 
订阅我的博客
XML聚合    FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
alvachien的公告
You will go through tough times, it's about coming through that.
文章分类
Alva Chien's Websites
Alva Chien's Photos
Always Dreaming of Something (else) - an Alva Chien's Blog
IT名人堂
Charles Petzold's Personal Website (Author of [Programming Windows])
Martin Fowler's Personal WebSite (Author of [Refactor])
潘爱民的专栏 (个人非常尊敬的一位大师,他翻的书让我可以不读原版, 现已加盟Microsoft)
芮祥麟的专栏(SAP Labs China的老大)
MFC/.Net网站荟萃
CodeGuru
CodeProject
GotDotNet - The Microsoft .NET Framework Community
MSDN
SQL Server Compact Edition
The Official Microsoft ASP.Net Site
The Synchronizer
WindowsClient.net: Windows Forms, Windows Presentation Foundation
顶尖IT公司
Accenture
HP
IBM
Intel
Microsoft Corp.
SAP AG
中国著名大学
上海交通大学
中国科学技术大学
北京大学
南京大学
南开大学
同济大学
复旦大学
浙江大学
清华大学
存档

原创  学习.NET (8) 实现派生类中Deep Copy的几种常用方法(通过ICloneable接口) 收藏

By Alva Chien
2008.10.03

跟C++编译器会默认提供一个Copy Constructor函数不同,C#中回避了这个问题。跟System.Object提供了一个充满歧义的Equals方法一样,System.Object还提供了一个MemberwiseClone方法,但是这个方法的名字依旧带来不小的误解,其实,这个函数只是实现了Shallow Copy,对.NET CLR中占绝大多数的Heap中使用的Reference Type,该函数只是复制了指针。

FCL提供了ICloneable接口,该接口只有一个Method:Clone(),返回值为System.Object。通过实现这个接口,该对象被认为是可以被Clone的,也就是可以被Copy的。至于是Deep Copy还是Shallow Copy就完全依赖于Clone方法是如何被实现了。

这里,遇到的第一个问题就是,当数个类之间有派生关系时,如何实现Deep Copy?

第一种方法,就是只在基类中实现ICloneable接口,并创建一个新的virtual方法,并在Clone方法中调用该virtual方法,所有的派生类只需要override这个virtual方法即可。

class Base : ICloneable
{
protected Int32 nBase = default(Int32);
public Object Clone()
{ return RealClone(null); }
protected virtual Object RealClone(Object obj)
{
if (obj == null) obj = new Base();
((Base)obj).nBase = this.nBase;
return obj;
}
}
class Derived : Base
{
protect Byte byDrv = default(Byte);
protected override Object RealClone(Object obj)
{
if (obj == null) obj = new Derived();
base.RealClone(obj);
((Derived)obj).byDrv = this.byDrv;
return obj;
}
}

第二种方法,为Base和Derived类都指定ICloneable接口。

class Base : ICloneable
{
protected Int32 nBase = default(Int32);
protected virtual Object Clone()
{
Base obj = new Base();
obj.nBase = this.nBase;
return obj;
}
}
class Derived : Base, ICloneable
{
protect Byte byDrv = default(Byte);
protected override Object Clone()
{
Derived obj = (Derived)base.Clone();
obj.byDrv = this.byDrv;
return obj;
}
}

第三种方法,采用类似C++的解决方案,为每个class实现一个Copy Constructor——即一个接受该类实例的Constructor。与第二种方法一样,同样为每个Class实现ICloneable方法。

class Base : ICloneable
{
protected Int32 nBase = default(Int32);
protected Base(Base other)
{ this.nBase = other.nBase; }
Object ICloneable.Clone()
{ return new Base(this); }
}
class Derived : Base, ICloneable
{
protect Byte byDrv = default(Byte);
protected Derived(Derived other) : base(other)
{ this.byDrv = other.byDrv; }
Object ICloneable.Clone()
{ return new Derived(this); }
}

好了,有了以上办法,可以创建支持Deep Copy的派生类了。

发表于 @ 2008年10月03日 15:15:00 | 评论( loading... ) | 编辑| 举报| 收藏

旧一篇:学习.NET(7) ISerializable接口简析之二 | 新一篇:Information Schema of SQL Server Compact 3.5

  • 发表评论
  • 评论内容:
  •  
Copyright © alvachien
Powered by CSDN Blog