小议.NET中的对象拷贝 [转贴]
2007-08-25 09:05
323 查看
from:http://terrylee.cnblogs.com/archive/2006/01/06/312493.html
小议.NET中的对象拷贝
引言:最近准备开始写探索设计模式系列之六原型模式,希望在春节前可以写完这篇文章。为了便于阐述,在这里先对.NET中的对象拷贝机制做一些总结。——写在Post100篇之际。概述
在.NET里面,如果需要实现对象拷贝功能,那么就要实现ICloneable接口。ICloneable接口中有一个Clone方法,可以在类中覆写实现自定义的拷贝方法。对象拷贝的实现方法有两种:浅拷贝(Shallow Copy)与深拷贝(Deep Copy)。
浅拷贝与深拷贝
浅拷贝是指当对象的字段值被拷贝时,字段引用的对象不会被拷贝。例如,如果一个对象有一个指向字符串的字段,并且我们对该对象做了一个浅拷贝,那么两个对象将引用同一个字符串。而深拷贝是对对象实例中字段引用的对象也进行拷贝的一种方式,所以如果一个对象有一个指向字符串的字段,并且我们对该对象做了一个深拷贝的话,我们将创建一个新的对象和一个新的字符串--新对象将引用新字符串。需要注意的是执行深拷贝后,原来的对象和新创建的对象不会共享任何东西;改变一个对象对另外一个对象没有任何影响。(出自《.NET框架程序设计(修订版)》,李建忠译)。简单地说,浅拷贝只复制顶级(Top-Level)对象,而深拷贝则复制对象及其子对象。
示意图如下:
代码说明
下面给出浅拷贝与深拷贝的两个例子,例子使用了ICloneable接口。C#中的数组是引用型的变量,下面通过数组来进行演示:
1.浅拷贝:
using System;
namespace CopyDemo
{
/// <summary>
/// ShallowCopy
/// </summary>
public class ShallowCopy : ICloneable
{
public int[] s = {4,5,6,7};
public Object Clone()
{
return this.MemberwiseClone();
}
public void Display()
{
foreach(int i in s)
{
Console.Write( i + ", ");
}
Console.WriteLine();
}
}
class Client
{
public static void Main(string[] args)
{
ShallowCopy obj1 = new ShallowCopy();
ShallowCopy obj2 = (ShallowCopy)obj1.Clone();
obj1.s[0] = 1;
obj1.Display();
obj2.Display();
Console.ReadLine();
}
}
}
运行结果:
1,5,6,7
1,5,6,7
ShallowCopy对象实现了一个浅拷贝,因此当对obj1进行拷贝时,其字段s并没有拷贝,这导致obj1与obj2的字段s都指向了同一个s,因此,当修改了obj1的s[0]后,obj2的s[0]也发生了变化。
2.深拷贝:
using System;
namespace CopyDemo
{
/// <summary>
/// DeepCoyp
/// </summary>
public class DeepCopy : ICloneable
{
public int[] s = {4,5,6,7};
// 默认构造函数
public DeepCopy()
{
}
// 供Clone方法调用的私有构造函数
private DeepCopy(int[] s)
{
this.s = (int[])s.Clone();
}
public Object Clone()
{
// 构造一个新的DeepCopy对象
return new DeepCopy(this.s);
}
public void Display()
{
foreach(int i in s)
{
Console.Write( i + ", ");
}
Console.WriteLine();
}
}
class Client
{
public static void Main(string[] args)
{
DeepCopy obj1 = new DeepCopy();
DeepCopy obj2 = (DeepCopy)obj1.Clone();
obj1.s[0] = 1;
obj1.Display();
obj2.Display();
Console.ReadLine();
}
}
}
运行结果:
1,5,6,7
4,5,6,7
这次在拷贝的时候,不但拷贝对象本身,连里面的数组字段一并拷贝。因此,最终打印出来的obj1与dobj2不同。
总结
在.NET中,由于提供了Icloneable接口,使得对象拷贝操作变得非常简单。
相关文章推荐
- 小议.NET中的对象拷贝
- 转贴:ASP.NET中Application,Session,Cookie和ViewState等对象用法
- 小议ADO.NET对象模型
- js对象的深拷贝和浅拷贝
- C++模板类 容器之map及对象副本 深/浅拷贝等问题浅析
- [NET]Net中的反射使用入门(根据类名和函数名,生成和调用对象的成员函数)
- 探讨C++中对象的“浅拷贝”与“深拷贝”
- js 对象和数组的深拷贝
- asp.net学习总结——Asp.net对象之Application对象、Server对象
- ASP.NET的常用内置对象
- asp.net控件开发基础(2)(转贴)
- spring的对象属性相同(类型,名字)拷贝
- asp.net控件开发基础(3)(转贴)
- 浅谈ADO.NET中的五个主要对象
- 一步一步教你使用AgileEAS.NET基础类库进行应用开发-WinForm应用篇-演示ORM对象与DataGridView的绑定技术-商品字典的另一个实现
- Asp.net中的几个对象
- JAVA对象拷贝
- 和我一起学CSLA.NET----创建业务对象3
- 收集学习asp.net比较完整的面向对象开发流程
- ASP.NET--Server对象
bytes[]
链接数据库任你选
Happy Teachers' Day