Deep Copy VS Shallow Copy
2013-01-14 09:28
274 查看
首先我们应该了解下什么是
深拷贝:不仅复制对象的基本类,同时也复制原来对象中的对象
C#中有两种类型变量,一种是值类型变量,一种是引用类型便利那个,对于值类型便利那个,深拷贝和浅拷贝都是通过复制操作实现的,其效果是一样的,将对象中的值类型的字段拷贝到新的对象中。这个很容易理解。本文重点讨论引用类型变量的拷贝机制和实现。
注意: string类型有点特殊,对于浅拷贝,按类值类型对象进行处理。
MemberwiseClone:创建当前Object的浅拷贝副本
MemberwiseClone方法创建一个浅表副本,方式是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制,如果该字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其副本引用同一个对象。
示例代码:
2 复制操作与使用Object类MemberwiseClone实现
对于引用类型的变量,我们有种误解,认为复制操作就是一种浅拷贝,其实是有区别的。
1浅拷贝对于引用类型对象中的值类型字段进行了逐位复制。赋值运算符只是把源对象的引用赋值给目的对象,两者引用同一个对象。
2浅拷贝后的对象的值类型字段更改不会反映到源对象,而赋值运算后的对象类型字段更改会反映到源对象。
==================================
在C#中,我们有
ICloneable接口包含一个成员Clone,以用于支持除MemberwiseClone所提供的克隆之外的克隆。Clone既可以为深层副本实现,也可以作为浅表层副本实现,在深层副本中,所有的对象都是重复的,而在浅表层副本中,只有顶级对象是重复的,并且顶级以下的对象包含引用。结果克隆必须与原始实例具有相同的类型。
2序列化/反序列化实现
不知道你有没有注意到DataSet对象,对于他提供的两个方法:
DataSet .Clone方法,复制DataSet的结构,包括所有DataTable架构,关系和约束,不复制任何数据。
新DataSet。其架构与当前DataSet的架构相同,但是不包含任何数据DataSet。注意如果已经创建的子类,则副本也将属于相同的子类。
DataSet. Copy方法复制该DataSet的结构和数据(若不理解相关术语,参考上篇博客 点击)
新的DataSet,具有与该DataSet相同的结构(表架构,关系和约束)和数据,
这两个既不是深,也不是浅拷贝,但是如果结合起来就是我们的深拷贝了。
序列化是将对象或对象图形转换为线性字节序列,以存储或传输到另一个位置的过程。反序列化是接受存储的信息并利用它重新创建对象的过程。
通过 ISerializable 接口,类可以执行其自己的序列化行为。
3通过反射实现
通过序列化/反射序列方式我们比较流畅的实现深拷贝,但是涉及
I/O操作,托管环境,就很耗费资源了。
这里利用反射特性。不详细解释了(也不很明白)
深拷贝与浅拷贝
浅拷贝:只复制对象的基本类型,对象类型,仍属于原来的引用深拷贝:不仅复制对象的基本类,同时也复制原来对象中的对象
C#中有两种类型变量,一种是值类型变量,一种是引用类型便利那个,对于值类型便利那个,深拷贝和浅拷贝都是通过复制操作实现的,其效果是一样的,将对象中的值类型的字段拷贝到新的对象中。这个很容易理解。本文重点讨论引用类型变量的拷贝机制和实现。
C#中引用类型对象的Copy操作有两种
为是上面说到的俩种。浅拷贝和深拷贝的区别:
浅拷贝是指将对象中的数值类型的字段拷贝到新的对象中,而对象中的引用字段则指复制它的一个引用到目标对象注意: string类型有点特殊,对于浅拷贝,按类值类型对象进行处理。
浅拷贝的实现
1 使用Ojbect类MemberwiseClone实现MemberwiseClone:创建当前Object的浅拷贝副本
MemberwiseClone方法创建一个浅表副本,方式是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制,如果该字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其副本引用同一个对象。
示例代码:
public class Person { public int Age { get; set; } public string Address { get; set; } public Name Name { get; set; } public object Clone() { return this.MemberwiseClone(); } } public class Name { public Name(string frisName,string lastName) { FristName = frisName; LastName = lastName; } public string FristName { get; set; } public string LastName { get; set; } }
2 复制操作与使用Object类MemberwiseClone实现
对于引用类型的变量,我们有种误解,认为复制操作就是一种浅拷贝,其实是有区别的。
1浅拷贝对于引用类型对象中的值类型字段进行了逐位复制。赋值运算符只是把源对象的引用赋值给目的对象,两者引用同一个对象。
2浅拷贝后的对象的值类型字段更改不会反映到源对象,而赋值运算后的对象类型字段更改会反映到源对象。
==================================
深拷贝的实现
相对于浅拷贝是指依照源对象为原型,创建一个新对象,将当前对象的所有字段进行执行逐位复制并支持递归,不管是值类型还是引用类型,不管是静态字段还是非静态字段。在C#中,我们有
三种方式实现深拷贝
1实现ICloneable接口,自定义拷贝功能ICloneable接口包含一个成员Clone,以用于支持除MemberwiseClone所提供的克隆之外的克隆。Clone既可以为深层副本实现,也可以作为浅表层副本实现,在深层副本中,所有的对象都是重复的,而在浅表层副本中,只有顶级对象是重复的,并且顶级以下的对象包含引用。结果克隆必须与原始实例具有相同的类型。
2序列化/反序列化实现
不知道你有没有注意到DataSet对象,对于他提供的两个方法:
DataSet .Clone方法,复制DataSet的结构,包括所有DataTable架构,关系和约束,不复制任何数据。
新DataSet。其架构与当前DataSet的架构相同,但是不包含任何数据DataSet。注意如果已经创建的子类,则副本也将属于相同的子类。
DataSet. Copy方法复制该DataSet的结构和数据(若不理解相关术语,参考上篇博客 点击)
新的DataSet,具有与该DataSet相同的结构(表架构,关系和约束)和数据,
这两个既不是深,也不是浅拷贝,但是如果结合起来就是我们的深拷贝了。
序列化是将对象或对象图形转换为线性字节序列,以存储或传输到另一个位置的过程。反序列化是接受存储的信息并利用它重新创建对象的过程。
通过 ISerializable 接口,类可以执行其自己的序列化行为。
3通过反射实现
通过序列化/反射序列方式我们比较流畅的实现深拷贝,但是涉及
I/O操作,托管环境,就很耗费资源了。
这里利用反射特性。不详细解释了(也不很明白)
相关文章推荐
- C++类中的4个特殊函数 && Object copy (Deep vs. Shallow vs. Lazy copy)
- 浅拷贝和深拷贝深入理解(shallow copy VS deep copy)
- shallow copy and deep copy (浅拷贝 vs 深拷贝)
- C# Tips-浅拷贝和深拷贝(shallow copy VS deep copy )
- Python Shallow Copy VS. Deep Copy (Python浅拷贝和深拷贝)
- C# Tips-浅拷贝和深拷贝(shallow copy VS deep copy )
- 浅拷贝和深拷贝(shallow copy VS deep copy )
- deep copy vs shallow copy
- Shallow vs. deep copy
- deep copy vs shallow copy
- Summary: Deep Copy vs. Shallow Copy vs. Lazy Copy
- difference between Python shallow copy and deep copy
- Shallow Copy(影子拷贝) VS Deep Copy(深拷贝)
- python deep copy and shallow copy
- Java Clone, Shallow Copy and Deep Copy
- .NET深入学习笔记(4):深拷贝与浅拷贝(Deep Copy and Shallow Copy)
- .NET深入学习笔记(4):深拷贝与浅拷贝(Deep Copy and Shallow Copy)(转载)
- [转载]:Shallow Copy and Deep Copy
- Python: Shallow and deep copy operations
- shallow copy and deep copy