转载自:http://blog.163.com/hr_msn/blog/static/21549405120132250396584/

深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。举个例子,一个人名叫张三,后来用他克隆(假设法律允许)了另外一个人,叫李四,不管是张三缺胳膊少腿还是李四缺胳膊少腿都不会影响另外一个人。比较典型的就是Value(值)对象,如预定义类型Int32,Double,以及结构(struct),枚举(Enum)等。

考虑以下写法

int source = int.MaxValue;//(1)初始化源对象为整数的最大值2,147,483,647

int dest = source;//(2)赋值,内部执行深拷贝

dest = 1024;//(3)对拷贝对象进行赋值

source = 2048;//(4)对源对象进行赋值

首先(2)中将source赋给dest,执行了深拷贝动作,其时dest和source的值是一样的,都是int.MaxValue;(3)对dest进行修改,dest值变为1024,由于是深拷贝,因此不会运行source,source仍然是int.MaxValue;(4)对source进行了修改,同样道理,dest仍然是1024,同时int.MaxValue的值也不变,仍然是2,147,483,647;只有source变成了2048。

再考虑以下写法

struct Point

{

public int X;

public int Y;

public Point(int x, int y)

{

X = x;

Y = y;

}

}

Point source = new Point(10, 20);

Point dest = source;

dest.X = 20

当dest.X属性变成20后,source的X属性仍然是10

  1. 浅拷贝是指源对象与拷贝对象共用一份实体,仅仅是引用的变量不同(名称不同)。对其中任何一个对象的改动都会影响另外一个对象。举个例子,一个人一开始叫张三,后来改名叫李四了,可是还是同一个人,不管是张三缺胳膊少腿还是李四缺胳膊少腿,都是这个人倒霉。比较典型的就有Reference(引用)对象,如Class(类)。

考虑以下写法

class Point

{

public int X;

public int Y;

public Point(int x, int y)

{

X = x;

Y = y;

}

}

Point source = new Point(10, 20);

Point dest = source;

dest.X = 20;

由于Point现在是引用对象,因此Point dest=source的赋值动作实际上执行的是浅拷贝,最后的结果应该是source的X字段值也变成了20。即它们引用了同一个对象,仅仅是变量明source和dest不同而已。

  1. 引用对象的浅拷贝原理

引用对象之间的赋值之所以执行的是浅拷贝动作,与引用对象的特性有关,一个引用对象一般来说由两个部分组成

(1)一个具名的Handle,也就是我们所说的声明(如变量)

(2)一个内部(不具名)的对象,也就是具名Handle的内部对象。它在Manged Heap(托管堆)中分配,一般由新增引用对象的New方法是进行创建

如果这个内部对象已被创建,那么具名的Handle就指向这个内部对象在Manged Heap中的地址,否则就是null(从某个方面来讲,如果这个具名的handle可以被赋值为null,说明这是一个引用对象,当然不是绝对)。两个引用对象如果进行赋值,它们仅仅是复制这个内部对象的地址,内部对象仍然是同一个,因此,源对象或拷贝对象的修改都会影响对方。这也就是浅拷贝

  1. 引用对象如何进行深拷贝

由于引用对象的赋值仅仅是复制具名Handle(变量)指向的地址,因此要对引用对象进行深拷贝就要重新创建一份该对象的实例,并对该对象的字段进行逐一赋值,如以下写法

class Point

{

public int X;

public int Y;

public Point(int x, int y)

{

X = x;

Y = y;

}

}

Point source = new Point(10, 20);

Point dest = new Point(source.X, source.Y);

//或以下写法

//Point dest = new Point()

//dest.X = source.X

//dest.Y = source.Y

其时,source和dest就是两个互相独立的对象了,两者的修改都不会影响对方

5.一些需要注意的东西

(1):String字符串对象是引用对象,但是很特殊,它表现的如值对象一样,即对它进行赋值,分割,合并,并不是对原有的字符串进行操作,而是返回一个新的字符串对象(类似深拷贝)

(2):Array数组对象是引用对象,在进行对象间赋值的时候,实际上返回的是源对象的另一份引用而已(类似浅拷贝);因此如果要对数组对象进行真正的复制(深拷贝),那么需要新建一份数组对象,然后将源数组的值逐一拷贝到目的对象中

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

  1. java 复制Map对象(深拷贝与浅拷贝)

      java 复制Map对象(深拷贝与浅拷贝) CreationTime--2018年6月4日10点00分 Author:Marydon 1.深拷贝与浅拷贝 浅拷贝:只复制对象的引用,两个引用仍然指向 ...

  2. 谈谈java中对象的深拷贝与浅拷贝

    知识点:java中关于Object.clone方法,对象的深拷贝与浅拷贝 引言: 在一些场景中,我们需要获取到一个对象的拷贝,这时候就可以用java中的Object.clone方法进行对象的复制,得到 ...

  3. PHP中对象的深拷贝与浅拷贝

    先说一下深拷贝和浅拷贝通俗理解 深拷贝:赋值时值完全复制,完全的copy,对其中一个作出改变,不会影响另一个 浅拷贝:赋值时,引用赋值,相当于取了一个别名.对其中一个修改,会影响另一个 PHP中, = ...

  4. JS对象复制(深拷贝、浅拷贝)

    如何在 JS 中复制对象 在本文中,我们将从浅拷贝(shallow copy)和深拷贝(deep copy)两个方面,介绍多种 JS 中复制对象的方法. 在开始之前,有一些基础知识值得一提:Javas ...

  5. JS 对象的深拷贝和浅拷贝

    转载于原文:https://www.cnblogs.com/dabingqi/p/8502932.html 这篇文章是转载于上面的链接地址,觉得写的非常好,所以收藏了,感谢原创作者的分享. 浅拷贝和深 ...

  6. 探究JS中对象的深拷贝和浅拷贝

    深拷贝和浅拷贝的区别 在讲深拷贝和浅拷贝的区别之前,回想一下我们平时拷贝一个对象时是怎么操作的?是不是像这样? var testObj1 = {a: 1, b:2}, testObj2=testObj ...

  7. Python 对象的深拷贝与浅拷贝 -- (转)

    本文内容是在<Python核心编程2>上看到的,感觉很有用便写出来,给大家参考参考! 浅拷贝 首先我们使用两种方式来拷贝对象,一种是切片,另外一种是工厂方法.然后使用id函数来看看它们的标 ...

  8. javascript学习总结之对象的深拷贝和浅拷贝

    前言 最近在写ES6的文章的时候发现重复遇到关于javascript深拷贝和浅拷贝的问题,然后查找了一些资料,根据资料和自己的理解做了以下笔记,毕竟javascript关于深拷贝和浅拷贝的问题在一些面 ...

  9. JS中实现数组和对象的深拷贝和浅拷贝

    数组的拷贝 > 数组的深拷贝,两层 var arr = [[1,2,3],[4,5,6],[7,8,9]]; var arr2 = []; 循环第一层数组 for(var i=0,len=arr ...

随机推荐

  1. myeclipse页面编辑框空格、回车符、对齐出现特殊字符

    myeclipse页面编辑框空格.回车符.对齐出现特殊字符 解决办法:window-preferences-general-editors-Text Editors    把show whitespa ...

  2. HDU 5688 Problem D map

    Problem D Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total S ...

  3. 初试 uTenux

    申请的的开发套件到目前还没到手,看到网友们都开始动手干了,我也是按捺不住了,所以就先在悠龙公司的主页下载了uTenux_V1.5.00r160.zip,打算看看,先了解一下. 下面是文件目录表: └─ ...

  4. BZOJ 1565 植物大战僵尸(最大权闭合图)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1565 题意:植物大战僵尸,一个n*m的格子,每 个格子里有一个植物,每个植物有两个属性: ...

  5. [3D] 基本概念

    [3D] 基本概念 环境光:对场景中所有的对象都提供了固定不变的照明.点光源:是从一个点发出的光.灯泡就可以理解为点光源.聚光源:正如它的的名字一样,是有方向和强弱的,电筒就是典型的聚光源. 方向光: ...

  6. 将文件读取到内存、打印pe结构

    #include <stdio.h> #include <malloc.h> #include <stdlib.h> #include <string.h&g ...

  7. 自动编号维护SNRO

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  8. 程序间数据共享与传递:EXPORT/IMPORT、SAP/ABAP Memory

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  9. Android下利用SQLite数据库实现增删改查

    1: 首先介绍如何利用adb查看数据库 1: adb shell 2: cd /data/data/包名/databases 3:  sqlite3 数据库 4   接下来就可以进行数据库的sql语法 ...

  10. ASP.Net MVC4中封装CSS和js冗余代码(不让其大篇的显示在前台上)

    (1)封装CSS和JS代码,使用调用的方式在前台进行调用.是开发看起来简洁和易于管理,可达到重用.   由于asp.netMVC4 框架 ,在封装js和CSS的时候,有如下规范: using Syst ...