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

如果大家不懂值类型和引用类型的区别,请先看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. C. Guess Your Way Out!

    C. Guess Your Way Out!                                                               time limit per ...

  2. Matrix multiplication hdu4920

    Problem Description Given two matrices A and B of size n×n, find the product of them. bobo hates big ...

  3. poj1328解题报告(贪心、线段交集)

    POJ 1328,题目链接http://poj.org/problem?id=1328 题意: 有一海岸线(x轴),一半是陆地(y<0).一半是海(y>0),海上有一些小岛(用坐标点表示P ...

  4. Android之Handler探索

    Handler背景理解: Handler被最多的使用在了更新UI线程中,但是,这个方法具体是什么样的呢?我在这篇博文中先领着大家认识一下什么是handler以及它是怎么样使用在程序中,起着什么样的作用 ...

  5. 关于hadoop2.4.1伪分布式系统的搭建

    1.准备Linux环境 1.0点击VMware快捷方式,右键打开文件所在位置 -> 双击vmnetcfg.exe -> VMnet1 host-only ->修改subnet ip ...

  6. 转:C++ 性能测试支持

    转: http://codinginet.com/articles/view/201606-use_gtestx_for_benchmark?simple=1&from=timeline&am ...

  7. SuperMapDeskTop中去除面图层边框

    0.项目中有个功能需要在超图DeskTop中修改面图层的符号,将要素的边框去掉.搞来搞去这个功能并不像ArcGisDeskTop一样直接有无边框的符号,通过请教,通过修改面图层的线样式的RGB颜色管理 ...

  8. live(),bind(),delegate()等事件绑定方法的区别及应用解析

    1 首先bind()方法是最直观的,但是也是弊端最大的. $('a').bind('click',function(){alert('that tickles!')}) 这和事件冒泡有直接关系,当我们 ...

  9. asp.net mvc开发的社区产品相关开发文档分享

    分享一款基于asp.net mvc框架开发的社区产品--近乎.目前可以在官网免费下载,下载地址:http://www.jinhusns.com/Products/Download?type=whp 1 ...

  10. iMAC——关闭自动弹出手机照片

    有时当自己的iPhone手机插入一台iMAC电脑时,会自动弹出自己iPhone手机的照片. 这相当影响人的隐私等等,所以顺便将方法(参考网络的)小记一篇博客. 一.OS X 10.10以上用户解决办法 ...