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. 快速开启Windows 的各种任务及 bat(ch)脚本

    MSC It is the Microsoft Management Console Snap-in Control File, like services.msc, devmgmt.msc (Dev ...

  2. SQL 刪除

    SQL 刪除 1.delete from table_name 2.drop table table_name drop table is different from deleting all of ...

  3. ubuntu lua安装

    #解压 tar -xzvf lua5.2.2.tar.gz #进入lua5.2.2文件夹 cd lua5.2.2 #执行make sudo make linux #提示如下错误: #lua.c:67: ...

  4. Linux中的简单命令

    history:打印你输过的命令      1.用户在shell中输入的命令会自动保存到内存缓冲区      2.在退出shell的时候,内存中的数据会刷新到磁盘文件:~/.bash_history ...

  5. mysql alter的常用用法

    增加字段,并加注释: ALTER TABLE table_name ADD field_name field_type [not null|null|default value][comment '注 ...

  6. 分页 page

    1.根据条件计算出数据的总数 2.import(page类); 3.实例化分页类 4.设置相关的参数 5.调用show()方法 // 导入分页类  import('ORG.Util.Page');$p ...

  7. jquery div拖动效果示例代码

    div拖动效果想必大家都有见到过吧,实现的方法也是有很多的,下面为大家将介绍使用jquery是如何实现的,感兴趣的朋友不要错过 复制代码代码如下: <%@ page language=" ...

  8. PHPCMS 核心代码与 www 分离部署

    为了满足更多用户二次开发的兴趣与爱好,同时,为了更加安全.可以通过修改入口代码的包含方式来让主程序和www程序分开. 先看下面目录结构: (图1) 我们需要将 phpcms 目录和 index.php ...

  9. 自己写的Python数据库连接类和sql语句拼接方法

    这个工具类十分简单和简洁. sql拼接方法 # encoding=utf-8 from django.http import HttpResponse from anyjson import seri ...

  10. GPU CUDA常量内存使用

    #include <cuda.h> #include <stdio.h> int getMulprocessorCount(){ cudaDeviceProp prop; cu ...