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

如果大家不懂值类型和引用类型的区别,请先看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#) - 单例模式(Singleton Pattern)【转】

    介绍 保证一个类仅有一个实例,并提供一个访问它的全局访问点. 示例 保证一个类仅有一个实例. Singleton using System; using System.Collections.Gene ...

  2. android网络请求之POST方法

    package com.jredu.helloworld.activity; import android.os.Bundle; import android.os.Handler; import a ...

  3. C++编译器的函数名修饰规则

    我们知道在C++中有函数重载这样一个东西,当我们定义了几个功能类似且函数名是一样的函数的时候,只要它的参数列表不同,编译是可以通过的,但是在C中是不可以的. double add(double a, ...

  4. 安装.Net framework 3.5 sp1报错的解决方法

    错误日志,提示: [11/22/07,18:04:40] Microsoft .NET Framework 2.0a: [2] Error: Installation failed for compo ...

  5. Volley 源码解析

    Volley 源码解析 1. 功能介绍 1.1. Volley Volley 是 Google 推出的 Android 异步网络请求框架和图片加载框架.在 Google I/O 2013 大会上发布. ...

  6. hdu 3635 Dragon Balls

    Dragon Balls Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot ...

  7. MongoDB - Introduction to MongoDB

    MongoDB is an open-source document database that provides high performance, high availability, and a ...

  8. django 学习-11 Django模型数据模板呈现

    1.for author in Author.objects.all(): for book in author.book_set.all(): print   book 2.vim blog/vie ...

  9. Linux C编程--fork()详解

    以下给出说明: fork函数 #include <sys/types.h>  #include <unistd.h> pid_t fork(void); fork调用失败则返回 ...

  10. Android应用源码基于安卓的校园二手交易系统客户端+服务端+数据库

    该源码是校园二手交易系统应用带服务端,也是一个基于安卓和javaweb的校园二手交易系统,包括整套安卓客户端.javaweb服务端.mysql数据库,可以进行基本的列表显示帖子.显示帖子详情.用户注册 ...