之前一直没有搞清楚深度复制和浅度复制的区别到底在哪里,今天彻底把这个东西弄懂了,写出来与到家共勉。

如果大家不懂值类型和引用类型的区别,请先看http://www.cnblogs.com/Autumoon/archive/2008/08/18/1270685.html,本来想自己写的,但刚好看到了这篇写的非常全面,就不自己写了。

大家都知道Object是所有类共同的基类,其有个方法是MemberwiseClone(),其用途为

我们可以通过这个方法来达到浅度复制的效果。

下面我们通过一个例子来阐述一下浅度复制,其与深度复制的区别在什么地方:

public class Content
{
public int Val;
}
public class Cloner
{
public Content MyContent = new Content(); public Cloner(int newVal)
{
MyContent.Val = newVal;
}
public object GetCopy()
{
return MemberwiseClone();
}
}

在这里我们有两个类,一个Content类,只有一个为值类型int的Val,还有个类是一个Cloner类,其有一个Content类型的成员,然后有个构造函数可以初始化成员,最后有一个GetCopy的方法,通过MemberwiseClone方法来复制自己。

下面我们通过一段代码来调用Cloner类:

static void Main(string[] args)
{
Cloner source = new Cloner();
Cloner target = (Cloner)source.GetCopy();//返回的是一个Object类型 需要做类型转换.
Console.WriteLine("target.MyContent.Val = {0}", target.MyContent.Val);
source.MyContent.Val = ;
Console.WriteLine("target.MyContent.Val = {0}", target.MyContent.Val);
Console.ReadKey();
}

结果是:

我们可以看到我们通过GetCopy()函数复制类source给target,但是当我们改变source的时候,source输出的值也跟着改变。由此我们可以得出,我们通过MemberwiseClone()复制的只是引用,即source和target的MyContent是相同的对象实例。这就是浅度复制,那我们如何实现深度复制呢,在.NET Framework中,给我们提供了ICloneable接口。

首先我们看下ICloneable接口:

// 摘要:
// 支持克隆,即用与现有实例相同的值创建类的新实例。
[ComVisible(true)]
public interface ICloneable
{
// 摘要:
// 创建作为当前实例副本的新对象。
//
// 返回结果:
// 作为此实例副本的新对象。
object Clone();
}

在上面那个例子中,我们只需要修改一些代码就可以了:

public class Cloner:ICloneable
{
public Content MyContent = new Content(); public Cloner(int newVal)
{
MyContent.Val = newVal;
}
//public object GetCopy()
//{
// return MemberwiseClone();
//}
public object Clone()
{
Cloner cloned = new Cloner(MyContent.Val);
return cloned;
}
}

为了做区别我把之前的代码放在上面,注释了的代码就是浅度复制,后面的为深度复制,我们看到差别在于用本实例的MyContent.Val重新生成了实例返回给目标,测试结果为:

这里如果MyContent的成员不是一个值类型,那么我们还需要进行深度,像下面一样:

public object Clone()
{
Cloner cloned = new Cloner();
cloned.MyContent = MyContent.Clone();
return cloned;
}

深度复制和浅度复制就是这样,关键是创建一个新的对象实例返回去,而不是把原来的对象实例返回回去。大家懂了吗?

.NET基础之深度复制和浅度复制的更多相关文章

  1. c#学习笔记-深度复制 与浅度复制

    关于值类型和引用类型: 浅度复制(shallow copy)只复制值类型(char,int )的值,而对于引用类型不会复制,浅度复制可以通过派生于System.Object的MemberwiseClo ...

  2. C#深度复制和浅度复制

    C#深度复制和浅度复制 复制一个值变量很简单,新建一个变量然后将原来的变量赋值过去就行,但是复制一个引用变量这种方法是不行的,如果不明白为什么可以先看看这篇解释 引用类型变量和值类型变量在赋值时的不同 ...

  3. 转载---Java集合对象的深度复制与普通复制

    原博文:http://blog.csdn.net/qq_29329775/article/details/49516247 最近在做算法作业时出现了错误,原因是没有弄清楚java集合的深度复制和浅度复 ...

  4. [No0000B9]C# 类型基础 值类型和引用类型 及其 对象复制 浅度复制vs深度复制 深入研究2

    接上[No0000B5]C# 类型基础 值类型和引用类型 及其 对象判等 深入研究1 对象复制 有的时候,创建一个对象可能会非常耗时,比如对象需要从远程数据库中获取数据来填充,又或者创建对象需要读取硬 ...

  5. 深度解析javascript中的浅复制和深复制

    原文:深度解析javascript中的浅复制和深复制 在谈javascript的浅复制和深复制之前,我们有必要在来讨论下js的数据类型.我们都知道有Number,Boolean,String,Null ...

  6. C++学习基础七——深复制与浅复制

    一.深复制与浅复制基本知识 深复制和浅复制,又称为深拷贝和浅拷贝. 深复制和浅复制的区别如下图1所示: 图1 图1表示的是,定义一个类CDemo,包含int a和char *str两个成员变量, 当深 ...

  7. java基础-浅复制与深复制的理解

    浅复制与深复制在很多编程语言中都有出现,那么什么是浅复制,什么是深复制呢? 要区分浅复制与深复制,首先我们要明确什么是复制,怎样才算是复制.复制的例子在生活中也随处可见,如复印一份文档,复制一段文字等 ...

  8. Java的深度克隆和浅度克隆

    说到克隆,其实是个比较简单的概念,跟现实生活正的克隆一样,复制一个一模一样的对象出来.clone()这个方法是从Object继承下来的,一个对象要实现克隆,需要实现一个叫做Cloneable的接口,这 ...

  9. 也来谈一谈js的浅复制和深复制

    1.浅复制VS深复制 本文中的复制也可以称为拷贝,在本文中认为复制和拷贝是相同的意思.另外,本文只讨论js中复杂数据类型的复制问题(Object,Array等),不讨论基本数据类型(null,unde ...

随机推荐

  1. E - 最短的名字

    Description 在一个奇怪的村子中,很多人的名字都很长,比如aaaaa, bbb and abababab. 名字这么长,叫全名显然起来很不方便.所以村民之间一般只叫名字的前缀.比如叫'aaa ...

  2. Debian 7 安装 Python3.4

    Debian 7 自带的python是2.7.3,要用最新的3.4版本怎么办?我们从官网下载压缩包自己编译. 一.安装编译用的包 $ sudo apt-get install build-essent ...

  3. 关于linux-Centos 7下mysql 5.7.9的rpm包的安装方式 (转)

    操作系统:Centos 7.1 mysql数据库版本:mysql5.7.9 mysql官方网站:http://www.mysql.com ------------------------------- ...

  4. java 调用OpenOffice将word格式文件转换为pdf格式

    一:环境搭建 OpenOffice 下载地址http://www.openoffice.org/ JodConverter 下载地址http://sourceforge.net/projects/jo ...

  5. oracle数据库 PSU,SPU(CPU),Bundle Patches 和 Patchsets 补丁号码快速参考 (文档 ID 1922396.1)

    数据库 PSU,SPU(CPU),Bundle Patches 和 Patchsets 补丁号码快速参考 (文档 ID 1922396.1) 文档内容   用途   详细信息   Patchsets ...

  6. x264命令参数与代码中变量的对应关系

    帧类型选项:  -I/--keyint i_keyint_max 最大IDR帧间距,默认为250  -i/--min-keyint i_keyint_min 最小IDR帧间距,默认为25  --sce ...

  7. Commons JXPath - Object Graph Traversal

    JXPath 提供了使用 Xpath 语法操纵符合 Java 类命名规范的 JavaBeans 的工具.也支持 maps.DOM 和其他对象模型.对于深层次结构的 JavaBean,使用 JXPath ...

  8. bootstrap学习起步篇:初识bootstrap之表单验证(二)

    学习bootstrap是个过程,它提供给我们的文档上有很详细的说明.包括常用的栅栏布局.页面元素等,这里就不啰嗦了,今天,我就来说下结合jquery的表单验证. 最开始不借助插件,我们需要自己去编写验 ...

  9. Android Studio ndk-Jni开发详细

    http://www.open-open.com/lib/view/open1451917048573.html Java Native Interface (JNI)标准是java平台的一部分,它允 ...

  10. C++转到C#历程零基础知识(持续增加)

    1.命名空间.类和源文件的关系:几个源文件用同一个命名空间时候,那么这几个源文件中的各个类之间的调用时可行的.他不会根据你的源文件分离而分开,因为最终编译后生成的是dll,这里来看你的几个源文件是没有 ...