1.基本的概念:

首先我们应该了解一下什么叫深拷贝与浅拷贝(Deep Copy and Shallow Copy)。

a.浅拷贝(Shallow Copy影子克隆):只复制对象的基本类型,对象类型,仍属于原来的引用。

b.深拷贝(Deep Copy 深度克隆):不紧复制对象的基本类,同时也复制原对象中的对象.完全产生新对象。

深拷贝与浅拷贝不同的是对于引用拷贝的处理,深拷贝将会在新对象中创建和原是对象中对应值类型的字段并且赋值。浅拷贝不会创建新引用类型,会返回相同的类 型引用。深拷贝会重新创建新对象,返回新对象的引用字。

2.深拷贝与浅拷贝实现机制:

从上面的概念我们了解了C#深拷贝与浅拷贝(Deep Copy and Shallow Copy)的不同之处。这个也就决定了两者有不同的实现方式。

对于值类型:

a.浅拷贝: 通过赋值等操作直接实现,将对象中的值类型的字段拷贝到新的对象中。
b.深拷贝:通过赋值等操作直接实现,将对象中的值类型的字段拷贝到新的对象中。 和浅拷贝相同

对于引用类型:

a.浅拷贝: MemberwiseClone 方法创建一个浅副本,方法是创建一个新对象,如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用原始对象,与原对象引用同一对象。

b.深拷贝:拷贝对象应用,也拷贝对象实际内容,也就是创建了一个新的改变新对象 不会影响到原始对象的内容
这种情况需要为其实现ICloneable接口中提供的Clone方法。

差别就是在对于引用类型的实现深拷贝和浅拷贝的时候的机制不同,前者是MemberwiseClone 方法实现,后者是通过继承实现ICloneable接口中提供的Clone方法,实现对象的深入拷贝。

3.代码实现

浅拷贝实例:

C# 代码   复制


using System;



namespace Prototype_Shallow{

//因为我们在FCL里面已经有这样的接口所以我们就不定义新的Prototype了

public class ConcretePrototype1 : ICloneable{

private int m_ID;

public int ID{

get{

return this.m_ID;

}

}

public ConcretePrototype1(int id){

this.m_ID = id;

}



public object Clone(){

return this.MemberwiseClone();

}

}



public class ConcretePrototype2 : ICloneable{

private int m_ID;

public int ID

{

get

{

return this.m_ID;

}

}

public ConcretePrototype2(int id){

this.m_ID = id;

}

public object Clone(){

return this.MemberwiseClone();

}

}



}

代码说明:

我们具体的原型都继承了接口ICloneable,同时也实现了该接口里面唯一个一个方法Clone。我们可以在客户端这样创建对象ConcretePrototype1 p1 = new ConcretePrototype1(1);

ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();

首先我们创建了对象p1,接下来我们用通过p1的科隆方法得到了对象c1,这就是一种浅拷贝(因为MemberwiseClone是浅拷贝)。

深拷贝实例:

 
C# 代码   复制

namespace Prototype_Deep{

using System.Collections;

public class ConcretePrototype : ICloneable

{

private int m_ID;

public int ID

{

get

{

return this.m_ID;

}

}



private ArrayList m_arrayList = new ArrayList();



public ConcretePrototype(int id)

{

this.m_ID = id;

this.m_arrayList.Add("FirstObject");

this.m_arrayList.Add("SecondObject");

// ...

}



public object Clone()

{

ConcretePrototype c = new ConcretePrototype(this.ID);

c.m_arrayList = new ArrayList();

c.m_arrayList.Add("FirstObject");

c.m_arrayList.Add("SecondObject");

return c;

}



public ConcretePrototype DeepClone(){

return (ConcretePrototype)this.Clone();

}

}

}

代码说明:

该代码显示了如何实现深拷贝,深拷贝的原则就是对于那些引用的字段您需要new(new之前想想是不是能用前面学过的某个创建型的模式实现,这是一个好的习惯)一个出来,然后对该字段里面的对象一一拷贝,这样以来很容易出现循环拷贝,所以说深拷贝要比浅拷贝更难一些。

客户端可以通过

ConcretePrototype p = new ConcretePrototype(1);

ConcretePrototype c = p.DeepClone();

来实现克隆一个新的对象。

C#中的深拷贝与浅拷贝的更多相关文章

  1. 浅谈Java中的深拷贝和浅拷贝(转载)

    浅谈Java中的深拷贝和浅拷贝(转载) 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: ...

  2. C语言中的深拷贝和浅拷贝

    //C语言中的深拷贝和浅拷贝 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #inc ...

  3. 浅谈Java中的深拷贝和浅拷贝

    转载: 浅谈Java中的深拷贝和浅拷贝 假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(bool ...

  4. 内功心法 -- Java中的深拷贝和浅拷贝

    写在前面的话:读书破万卷,编码如有神--------------------------------------------------------------------这篇博客主要来谈谈" ...

  5. **Python中的深拷贝和浅拷贝详解

    Python中的深拷贝和浅拷贝详解   这篇文章主要介绍了Python中的深拷贝和浅拷贝详解,本文讲解了变量-对象-引用.可变对象-不可变对象.拷贝等内容.   要说清楚Python中的深浅拷贝,需要 ...

  6. javascript中的深拷贝与浅拷贝

    javascript中的深拷贝与浅拷贝 基础概念 在了解深拷贝与浅拷贝的时候需要先了解一些基础知识 核心知识点之 堆与栈 栈(stack)为自动分配的内存空间,它由系统自动释放: 堆(heap)则是动 ...

  7. JavaScript中的深拷贝和浅拷贝!【有错误】还未修改!请逛其他园子!

    JavaScript中的深拷贝和浅拷贝! 浅拷贝 1.浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用.{也就是拷贝的是地址!简而言之就是在新的对象中修改深层次的值也会影响原来的对象!} // 2.深 ...

  8. 001 说说Python中的深拷贝和浅拷贝

    在Python编程中忽略深拷贝和浅拷贝可能会造成未知的风险. 比如我们打算保存一份原始对象的副本作为上一状态的记录,此后修改原始对象数据时,若是副本对象的数据也发生改变,那么这就是一个严重的错误. 注 ...

  9. Objective-C中的深拷贝和浅拷贝

    在Objective-C中对象之间的拷贝分为浅拷贝和深拷贝.说白了,对非容器类的浅拷贝就是拷贝对象的地址,对象里面存的内容仍然是一份,没有新的内存被分配.对非容器类的深拷贝就是重写分配一块内存,然后把 ...

  10. python中的深拷贝与浅拷贝

    深拷贝和浅拷贝 浅拷贝的时候,修改原来的对象,浅拷贝的对象不会发生改变. 1.对象的赋值 对象的赋值实际上是对象之间的引用:当创建一个对象,然后将这个对象赋值给另外一个变量的时候,python并没有拷 ...

随机推荐

  1. Java实战之03Spring-02Spring的核心之IoC

    二.Spring的核心之IoC(Inversion of Control 控制反转) 1.IoC是什么? 回顾:连接池原理中的使用. 注意:我们在连接池原理中是使用构造函数注入的,当然还可以通过提供s ...

  2. (poj)1502 MPI Maelstrom

    题目链接:http://poj.org/problem?id=1502 Description BIT has recently taken delivery of their processor A ...

  3. dialog的传值

    A页面 等待B页面返回值的textBox:<asp:TextBox ID="TextBox1" runat="server"></asp:Te ...

  4. Linux网络应用编程之VLAN(Packet Tracer仿真)

    VLAN 一.VLAN概述 VLAN(虚拟局域网):将多个设备和用户在逻辑上联网在一起,这些设备和用户不受物理位置的限制(物理设备可以在不同的地方),但是他们的通信就好像在同一网段中一样,这就叫VLA ...

  5. make menuconfig出错需要安装文件

    $ make menuconfig *** Unable to find the ncurses libraries or the *** required header files. *** 'ma ...

  6. Visual Assist安装、破解方法

    1.从各种渠道下载Visual Assist安装程序及破解补丁. 2.在路径(Win7):C:\Users\UserName\AppData\Local\Microsoft\VisualStudio\ ...

  7. 使用weinre通过PC浏览器调试手机网页

    Weinre是什么? Weinre代表Web Inspector Remote,是一种远程调试工具.举个例子,在电脑上可以即时的更改手机上对应网页的页面元素.样式表, 或是查看Javascript变量 ...

  8. sed线上经典案例之-同时替换多个字符串

    回答网友请教的一个问题:配置文件如下:[aaa]cfg1=aaaxxxx=bbbcfg2=ccccfg3=ddd[bbb]cfg1=eeeyyyy=fffcfg2=gggcfg3=hhhcfg4=ii ...

  9. 【Http】Http权威指南

    God Is Coder 2012-10-17 22:25 阅读:77 评论:0   <http权威指南>阅读笔记(十二) God Is Coder 2012-10-17 22:04 阅读 ...

  10. Runtime - 01

    Runtime是想要做好iOS开发,或者说是真正的深刻的掌握OC这门语言所必需理解的东西.最近在学习Runtime,有自己的一些心得,整理如下, 什么是Runtime 我们写的代码在程序运行过程中都会 ...