深复制VS浅复制(MemberwiseClone方法介绍)

MemberwiseClone方法,属于命名空间System,存在于程序集 mscorlib.dll中。返回值是System.Object。其含义是:创建一个当前object对象的浅表副本。

MSDN中的官方解释是:

MemberwiseClone 方法创建一个浅表副本,方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。

例如:考虑引用对象 A 和 B 的被称为 X 的对象。对象 B 依次引用对象 C。X 的浅表副本创建一个新对象 X2,该对象也引用对象 A 和 B。相比而言,X 的深层副本创建一个新对象 X2,该对象引用新对象 A2 和 B2(分别为 A 和 B 的副本)。B2 又引用新对象 C2,C2 是 C 的副本。该示例阐释了浅层和深层复制操作之间的区别。

有很多方法可以实现深层复制操作,前提是浅表复制操作由MemberwiseClone 方法执行但不符合您的需求。这些要求包括:

1、调用要复制的对象的类构造函数以创建含有从第一个对象中提出的属性值的第二个对象。这假定对象的值完全由类构造函数定义。

2、调用MemberwiseClone 方法创建的对象的浅表副本,然后将指定新的对象,其值均相同,原始对象的任何属性或字段的值是引用类型。该示例中的DeepCopy 方法阐释了这种方法。

3、序列化要深层复制的对象,然后将序列化的数据还原到另一个对象变量。

4、 使用带递归的反射执行的深层复制操作。

估计看到这你早就已经是晕的不行了吧!呵呵,本菜鸟也是这样滴……在自己的不懈努力之下,并且从实例中试验过后才弄明白,原来这个所谓的浅复制和深复制是如此的简单啊!

其实,用咱们在windows操作系统中使用的快捷方式和源文件的关系来理解就简单了!相信大家从玩电脑开始可能都遇到过这样的尴尬局面,就是用u盘复制了电脑的文件,然后兴高采烈的去打印,然后一到打印店打开u盘中复制到的文件,“纳尼!怎么打不开呢!原来是自己复制了一个快捷方式,额&……”(哈哈……说到这,估计有的人就非常有共鸣了啦!是吧?)

快捷方式:其实就相当于是引用源文件,快捷方式中并不存在源文件对象,只是存放了一个源文件的地址,这个地址指向源文件,当你双击的时候,windows会根据这个地址去你的电脑寻找这个源文件并打开。只复制一个快捷方式,这就相当于是浅复制啦

复制源文件:将文件的数据都复制过来,这就是所谓的深复制。

还不懂?看一个实例吧!(灵感来自:大话设计模式之原型模式——简历复制)

先看类图:

浅复制:

客户端代码如下

[csharp] view plaincopy

  1. Resume Rbill = new Resume("bill");
  2. Rbill.SetPersonalInfo("man", "11");
  3. Rbill.SetWorkExperience("2015-1-2-2015-12-10", "IBM");
  4. Resume Rcindy = (Resume)Rbill.Clone();
  5. Rcindy.SetWorkExperience("2015-1-2至2015-11-11", "Microsoft");
  6. Resume Rll = (Resume)Rbill.Clone();
  7. Rll.SetPersonalInfo("rll", "99");
  8. Rll.SetWorkExperience("2015-1-2至2015-11-11", "甲骨文");
  9. Rbill.Display();
  10. Rcindy.Display();
  11. Rll.Display();
  12. Console.Read();

类的代码如下:

[csharp] view plaincopy

  1. public class Resume : ICloneable
  2. {
  3. private string name;
  4. private string age;
  5. private string sex;
  6. //private string workDate;
  7. // private string company;
  8. private Workexperience work;
  9. public Resume(string strName)
  10. {
  11. this.name = strName;
  12. work = new Workexperience();        //在初始化Resume的同时实例化一个Workexperience对象。
  13. }
  14. //提供clone 方法调用的私有构造函数,以便克隆数据。
  15. private Resume(Workexperience work)
  16. {
  17. this.work = (Workexperience)work.Clone();
  18. }
  19. public void SetPersonalInfo(string sex, string age)
  20. {
  21. this.sex = sex;
  22. this.age = age;
  23. }
  24. public void SetWorkExperience(string workDate, string company)
  25. {
  26. work.WorkDate  = workDate;
  27. work.Company  = company;
  28. }
  29. public void Display()
  30. {
  31. Console.WriteLine("{0},{1},{2}", name, sex, age);
  32. Console.WriteLine("{0},{1}", work .WorkDate , work.Company );   // 引用work类的属性、字段。
  33. }
  34. public object Clone()
  35. {
  36. Resume obj = new Resume(this.work);  //调用私有构造函数,完成克隆,并给简历对象的相关字段赋值,返回深复制简历对象
  37. obj.name = name;
  38. obj.sex = sex;
  39. //obj.workDate = workDate;
  40. obj.age = age;
  41. return obj;
  42. //return (object)this.MemberwiseClone();
  43. }
  44. }
  45. class Workexperience : ICloneable
  46. {
  47. private string workDate;
  48. private string company;
  49. public string WorkDate
  50. {
  51. get { return workDate; }
  52. set { workDate = value; }
  53. }
  54. public string Company
  55. {
  56. get { return company; }
  57. set { company = value; }
  58. }
  59. public object Clone()
  60. {
  61. return (object)this.MemberwiseClone();
  62. }
  63. }

看到这里,有没有豁然开朗的赶脚呢?

ok,that‘s it! thank you for your attention!

时间: 2024-11-28 23:59:35

深复制VS浅复制(MemberwiseClone方法介绍)的相关文章

clone()方法、深复制和浅复制

clone方法 Java中没有明确提供指针的概念和用法,而实质上没个new语句返回的都是一个指针的引用,只不过在大部分情况下开发人员不需要关心如何去操作这个指针而已. 在实际编程中,经常会遇到从某个已有对象A创建出另一个与A具有相同状态的对象B,并且B的修改不会影响到A的情况,例如Prototype(原型)模式中,就需要clone一个对象实例. 仅仅通过简单的复制操作显然无法达到这个目的,而Java提供了一个简单有效的clone()方法来满足这个需求. Java中所有的类默认都继承自Object

.NET中深复制与浅复制

概述: 在.NET里面,提供对象复制的功能,前提是实现ICloneable接口.ICloneable接口中有一个Clone方法, 可以在类中覆写实现自定义的拷贝方法.对象复制的实现方法有两种:深复制和浅复制. 深复制和浅复制: 浅复制,浅复制是指源对象与复制出来的对象共用一份实体,对其中任何一个对象的改动都会影响另外一个对象.相当于复制了指针. 深复制:指源对象与复制对象互相独立,为新对象重新分配了一段内存空间,并复制源对象的内容.其中任何一个对象的改动都不会对另外一个对象造成影响. 深浅复制与

Java中的clone()----深复制,浅复制

这篇文章主要介绍了Java中对象的深复制(深克隆)和浅复制(浅克隆) ,需要的朋友可以参考下 1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵深复制(深克隆) 被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量.那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象.换言之,深复制把要复制的对象所引用

js中对象的复制,浅复制(浅拷贝)和深复制(深拷贝)

在js中,我们经常复制一个对象,复制数据,那么就会有人问了,怎么复制,今天鹏哥就带来js中的复制方法. JS中对象分为基本类型和复合(引用)类型,基本类型存放在栈内存,复合(引用)类型存放在堆内存. 堆内存用于存放由new创建的对象,栈内存存放一些基本类型的变量和对象的引用变量. 至于堆内存和栈内存的区别介绍,你们可以百度看看. 下面开始讲解复制: 这种只是简单的变量,内存小,我们直接复制不会发生引用. var a=123; var b=a; a=123456; alert(a); //1234

iOS 集合的深复制与浅复制

概念 对象拷贝有两种方式:浅复制和深复制.顾名思义,浅复制,并不拷贝对象本身,仅仅是拷贝指向对象的指针:深复制是直接拷贝整个对象内存到另一块内存中. 一图以蔽之 再简单些说:浅复制就是指针拷贝:深复制就是内容拷贝. 集合的浅复制 (shallow copy) 集合的浅复制有非常多种方法.当你进行浅复制时,会向原始的集合发送retain消息,引用计数加1,同时指针被拷贝到新的集合. 现在让我们看一些浅复制的例子: NSArray *shallowCopyArray = [someArray cop

深复制与浅复制

概念 对象拷贝有两种方式:浅复制和深复制.顾名思义,浅复制,并不拷贝对象本身,仅仅是拷贝指向对象的指针:深复制是直接拷贝整个对象内存到另一块内存中. 一图以蔽之 再简单些说:浅复制就是指针拷贝:深复制就是内容拷贝. 集合的浅复制 (shallow copy) 集合的浅复制有非常多种方法.当你进行浅复制时,会向原始的集合发送retain消息,引用计数加1,同时指针被拷贝到新的集合. 现在让我们看一些浅复制的例子: NSArray *shallowCopyArray = [someArray cop

OC 中 的copy 功能 深复制 和 浅复制 的 区别

系统的类要是实现copy拷贝的功能,必须先签订拷贝NSCopying的协议,然后实现对应的方法 在.h文件中得@interface Boy : NSObject 的后面需要签订拷贝NSCopying的协议 例子: 在.h文件中 @interface Boy : NSObject<NSCopying> 1. Boy类使用copy的方法 例子: Boy *boy =[Boy boyWithName:@"zhangyangyang" hobby:@"wan"]

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

一.深复制与浅复制基本知识 深复制和浅复制,又称为深拷贝和浅拷贝. 深复制和浅复制的区别如下图1所示: 图1 图1表示的是,定义一个类CDemo,包含int a和char *str两个成员变量, 当深复制时,A中的指针str与B中的指针str指向不同的地址,只是地址所指向的数据相同. 当浅复制时,A中的指针str与B中的指针str指向相同的地址. 1.浅复制:如果我们自己不实现复制构造函数,则C++会自动合成一个复制构造函数,又称为浅复制构造函数. 2.深复制:如果使用指针或者系统资源(如数据库

实现 $.extend 的深复制和浅复制

$.extend 是jquery常用的一个方法,该方法通过传第一个布尔型参数可以指定为深复制还是浅复制,如何使用不在本文讨论. 先来理解下什么是深复制: var ob1 = {'name' : 'Jack' , 'child' : {'name' : 'Tom', 'age' : '7'}}; var ob2 = {'name' : 'Rose' , 'child' : {'name' : 'Mike'}}; 浅复制后的结果:{'name' : 'Jack' ,'child' : {'name'

iOS深复制和浅复制

1.copy关键字 1> 浅拷贝与深拷贝 浅拷贝就是对内存地址的复制,让目标对象指针和源对象指向同一片内存空间. 深拷贝是指拷贝对象的具体内容,而内存地址是自主分配的,拷贝结束之后,两个对象虽然存的值是相同的,但是内存地址不一样,两个对象也互不影响,互不干涉. 2> copy和mutableCopy copy:对于可变对象为深复制,引用计数不改变;对于不可变对象是浅复制,引用计数每次加一.始终返回一个不可变对象. mutableCopy:始终是深复制,引用计数不改变.始终返回一个可变对象. 3