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

原创 2008年10月03日 15:15:00

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的派生类了。

版权声明:© 2004 - 2016 Alva Chien, All Rights Reserved.

ICloneable 的方法实现 不要轻易使用ICloneable

ICloneable听起来是个好主意:可以为那些支持复制的类型实现ICloneable接口。如果不想支持复制,那就不要实现它。但是我们的类型并非活在真空中。让一个类型支持ICloneable接口会影响...
  • bugDemo
  • bugDemo
  • 2012年08月28日 23:45
  • 2310

【.NET基础】——ShadowCopy And DeepCopy

在介绍.NET平台下的ShadowCopy And DeepCopy之前,我们先来了解两个概念——值类型 and 引用类型。 值类型 and 引用类型 ...
  • u013035538
  • u013035538
  • 2015年01月17日 21:04
  • 1345

ICloneable接口的浅拷贝与深拷贝

ICloneable接口支持克隆,即用与现有实例相同的值创建类的新实例。ICloneable 接口包含一个成员 Clone,它用于支持除 MemberwiseClone (创建当前 Object的...
  • sujing910206
  • sujing910206
  • 2011年12月29日 21:32
  • 1439

Deep copy(深拷贝)和shallow copy(浅拷贝)的区别

deep copy 和shallow copy 都是用于对象之间的拷贝,简单来说,如果
  • Andrewseu
  • Andrewseu
  • 2014年05月24日 18:03
  • 2311

[NET]深度拷贝的实现(DeepCopy)

实现思想:  对象-〉序列化-〉二进制流-〉反序列化-〉新的对象DotNet 代码:    public static  Object DeepClone(Object srcObject)     ...
  • szwangdf
  • szwangdf
  • 2006年09月12日 14:45
  • 1431

漫谈deepcopy(深拷贝)和shallowcopy(浅拷贝)

浅拷贝:只复制当前的对象,对该对象内部的引用(其他类对象作为自己的元素-也叫对其他对象的引用)不能复制(在堆内存中从新创建空间,内容相同,但地址不同)。 深拷贝:对对象内部的引用均复制,是创建一个新的...
  • u010111016
  • u010111016
  • 2016年06月15日 20:23
  • 2135

C#中基类、派生类以及使用接口来实现多重继承

继承是面向对象程序设计中最重要的概念之一。继承允许我们根据一个类来定义另一个类来定义一个类,这使得创建和维护应用程序变得更容易。同时也有利于重用代码和节省开发时间。 当创建一个类时,程序员不需要完全...
  • vs_the_old_boy
  • vs_the_old_boy
  • 2016年08月02日 13:32
  • 1621

C# 实现可克隆(ICloneable)的类型

问题 有时需要创建一个自定义类型,它能为开发人员提供一种简单的机制来创建该类型实例的副本。 解决方案 实现System.ICloneable接口。 原理 如果我们有两个值类型的变量,将其...
  • u012413535
  • u012413535
  • 2015年12月20日 20:36
  • 1412

python中copy与deepcopy的使用

讨论copy与deepcopy的区别这个问题要先搞清楚python中的引用、python的内存管理。 python中的一切事物皆为对象,并且规定参数的传递都是对象的引用。可能这样说听起来比较难懂。参...
  • kuaileboy1989
  • kuaileboy1989
  • 2015年03月09日 09:52
  • 2796

通过实现接口 ICloneable 复制对象

using System;using System.Collections.Generic;using System.Text;using System.Reflection;using System...
  • gooer
  • gooer
  • 2009年03月11日 11:45
  • 1900
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:学习.NET (8) 实现派生类中Deep Copy的几种常用方法(通过ICloneable接口)
举报原因:
原因补充:

(最多只允许输入30个字)