首页 / 软件开发 / .NET编程技术 / .NET深入学习笔记(4):深拷贝与浅拷贝(Deep Copy and Shallow Copy)
.NET深入学习笔记(4):深拷贝与浅拷贝(Deep Copy and Shallow Copy)2011-01-06 博客园 Frank Xu Lei今天继续利用准备WSE安全开发文章的空闲时间,完善《.NET深入学习笔记》系列(基本都是.Net重要的知识点,我都做了详细的总结,是什么、为什么、和怎么实现)。想必很多人也接触过这两个概念。做过C++的人对深浅拷贝的概念一定不会陌生。而其很多C#高级软件工程师的面试里也会问到深浅拷贝相关的问题。我今天就在总结一下,并且添加了详细的代码实现,与大家分享。一起学习一下C#的深拷贝与浅拷贝(Deep Copy and Shallow Copy)的机制。全文还是分三部分:1.基本概念 2.深拷贝与浅拷贝实现机制 3.代码实现和分析 4.总结。相面我们来进入正式的学习。1.基本的概念:首先我们应该了解一下什么叫深拷贝与浅拷贝(Deep Copy and Shallow Copy)。a.浅拷贝(Shallow Copy影子克隆):只复制对象的基本类型,对象类型,仍属于原来的引用。b.深拷贝(Deep Copy 深度克隆):不紧复制对象的基本类,同时也复制原对象中的对象.完全产生新对象。我们知道,在C++中有拷贝构造函数和拷贝赋值函数的概念。浅拷贝就是成员数据之间的一一赋值:把值赋给一一赋给要拷贝的值。但是可能会有这样的情况:对象还包含资源,这里的资源可以值堆资源,或者一个文件。当值拷贝的时候,两个对象就有用共同的资源,同时对资源可以访问,这样就会出问题。深拷贝就是用来解决这样的问题的,它把资源也赋值一次,使对象拥有不同的资源,但资源的内容是一样的。对于堆资源来说,就是在开辟一片堆内存,把原来的内容拷贝。如果你拷贝的对象中引用了某个外部的内容(比如分配在堆上的数据),那么在拷贝这个对象的时候,让新旧两个对象指向同一个外部的内容,就是浅拷贝;如果在拷贝这个对象的时候为新对象制作了外部对象的独立拷贝,就是深拷贝这个C#里的概念与C++类似。我们可以参考以前的概念理解。 深拷贝与浅拷贝之间的区别基本可以从定义看出。首先浅拷贝是指将对象中的数值类型的字段拷贝到新的对象中,而对象中的引用型字段则指复制它的一个引用到目标对象。如果改变目标对象中引用型字段的值他将反映在原是对象中,也就是说原始对象中对应的字段也会发生变化。深拷贝与浅拷贝不同的是对于引用拷贝的处理,深拷贝将会在新对象中创建和原是对象中对应值类型的字段并且赋值。浅拷贝不会创建新引用类型,会返回相同的类型引用。深拷贝会重新创建新对象,返回新对象的引用字。C#重的观察者模式就是浅拷贝的例子。我们保留的只是对象的副本。2.深拷贝与浅拷贝实现机制:从上面的概念我们了解了C#深拷贝与浅拷贝(Deep Copy and Shallow Copy)的不同之处。这个也就决定了两者有不同的实现方式。对于值类型:a.浅拷贝:通过赋值等操作直接实现,将对象中的值类型的字段拷贝到新的对象中。b.深拷贝:通过赋值等操作直接实现,将对象中的值类型的字段拷贝到新的对象中。和浅拷贝相同对于引用类型:a.值类型:MemberwiseClone 方法创建一个浅副本,方法是创建一个新对象,如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用原始对象,与原对象引用同一对象。b.引用类型:拷贝对象应用,也拷贝对象实际内容,也就是创建了一个新的改变新对象 不会影响到原始对象的内容这种情况需要为其实现ICloneable接口中提供的Clone方法。差别就是在对于引用类型的实现深拷贝和浅拷贝的时候的机制不同,前者是MemberwiseClone 方法实现,后者是通过继承实现ICloneable接口中提供的Clone方法,实现对象的深入拷贝。