您的位置:首页 > 运维架构

Deep Copy VS Shallow Copy

2013-01-14 09:28 274 查看
首先我们应该了解下什么是

深拷贝与浅拷贝

浅拷贝:只复制对象的基本类型,对象类型,仍属于原来的引用
深拷贝:不仅复制对象的基本类,同时也复制原来对象中的对象


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操作,托管环境,就很耗费资源了。
这里利用反射特性。不详细解释了(也不很明白)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: