深复制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会根据这个地址去你的电脑寻找这个源文件并打开。只复制一个快捷方式,这就相当于是浅复制啦
复制源文件:将文件的数据都复制过来,这就是所谓的深复制。
还不懂?看一个实例吧!(灵感来自:大话设计模式之原型模式——简历复制)
先看类图:
浅复制:
客户端代码如下
- Resume Rbill = new Resume("bill");
- Rbill.SetPersonalInfo("man", "11");
- Rbill.SetWorkExperience("2015-1-2-2015-12-10", "IBM");
- Resume Rcindy = (Resume)Rbill.Clone();
- Rcindy.SetWorkExperience("2015-1-2至2015-11-11", "Microsoft");
- Resume Rll = (Resume)Rbill.Clone();
- Rll.SetPersonalInfo("rll", "99");
- Rll.SetWorkExperience("2015-1-2至2015-11-11", "甲骨文");
- Rbill.Display();
- Rcindy.Display();
- Rll.Display();
- Console.Read();
类的代码如下:
- public class Resume : ICloneable
- {
- private string name;
- private string age;
- private string sex;
- //private string workDate;
- // private string company;
- private Workexperience work;
- public Resume(string strName)
- {
- this.name = strName;
- work = new Workexperience(); //在初始化Resume的同时实例化一个Workexperience对象。
- }
- //提供clone 方法调用的私有构造函数,以便克隆数据。
- private Resume(Workexperience work)
- {
- this.work = (Workexperience)work.Clone();
- }
- public void SetPersonalInfo(string sex, string age)
- {
- this.sex = sex;
- this.age = age;
- }
- public void SetWorkExperience(string workDate, string company)
- {
- work.WorkDate = workDate;
- work.Company = company;
- }
- public void Display()
- {
- Console.WriteLine("{0},{1},{2}", name, sex, age);
- Console.WriteLine("{0},{1}", work .WorkDate , work.Company ); // 引用work类的属性、字段。
- }
- public object Clone()
- {
- Resume obj = new Resume(this.work); //调用私有构造函数,完成克隆,并给简历对象的相关字段赋值,返回深复制简历对象
- obj.name = name;
- obj.sex = sex;
- //obj.workDate = workDate;
- obj.age = age;
- return obj;
- //return (object)this.MemberwiseClone();
- }
- }
- class Workexperience : ICloneable
- {
- private string workDate;
- private string company;
- public string WorkDate
- {
- get { return workDate; }
- set { workDate = value; }
- }
- public string Company
- {
- get { return company; }
- set { company = value; }
- }
- public object Clone()
- {
- return (object)this.MemberwiseClone();
- }
- }
看到这里,有没有豁然开朗的赶脚呢?
ok,that's it! thank you for your attention!
深复制VS浅复制(MemberwiseClone方法介绍)的更多相关文章
- clone()方法、深复制和浅复制
clone方法 Java中没有明确提供指针的概念和用法,而实质上没个new语句返回的都是一个指针的引用,只不过在大部分情况下开发人员不需要关心如何去操作这个指针而已. 在实际编程中,经常会遇到从某个已 ...
- C#深复制与浅复制
C#深复制与浅复制 C#中对于数据的复制机制虽然简单但是容易让人误解.C#数据类型大体分为值类型(value type)与引用类型(reference type).对于值类型数据,复制的时候直接将数据 ...
- Java中的clone()----深复制,浅复制
这篇文章主要介绍了Java中对象的深复制(深克隆)和浅复制(浅克隆) ,需要的朋友可以参考下 1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他 ...
- .Net深复制、浅复制
在.Net,大家都知道引用类型的深复制.浅复制吧. ,一般int等值类型是值类型(复制时是直接传值),一般的类(List<T>,Class)是引用类型(复制时传地址),默认是浅复制.若ob ...
- C++学习基础七——深复制与浅复制
一.深复制与浅复制基本知识 深复制和浅复制,又称为深拷贝和浅拷贝. 深复制和浅复制的区别如下图1所示: 图1 图1表示的是,定义一个类CDemo,包含int a和char *str两个成员变量, 当深 ...
- php对象当参数传递 && php深复制和浅复制
把对象当参数传递给方法,在方法里改过对象后,影响到外面的对象 因为对象是引用传递过去的 class Book { public $name; public function __construct( ...
- iOS 集合的深复制与浅复制
概念 对象拷贝有两种方式:浅复制和深复制.顾名思义,浅复制,并不拷贝对象本身,仅仅是拷贝指向对象的指针:深复制是直接拷贝整个对象内存到另一块内存中. 一图以蔽之 再简单些说:浅复制就是指针拷贝:深复制 ...
- Java中对象的深复制和浅复制详解
1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵ ...
- Java中的深复制与浅复制
1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不 复制它所引用的对象. ...
- 实现 $.extend 的深复制和浅复制
$.extend 是jquery常用的一个方法,该方法通过传第一个布尔型参数可以指定为深复制还是浅复制,如何使用不在本文讨论. 先来理解下什么是深复制: var ob1 = {'name' : 'Ja ...
随机推荐
- 容器编排系统K8s之NetworkPolicy资源
前文我们了解了k8s的网络插件flannel的基础工作逻辑,回顾请参考:https://www.cnblogs.com/qiuhom-1874/p/14225657.html:今天我们来聊一下k8s上 ...
- win8.1下jdk的安装和环境变量的配置 eclipse的安装和汉化
1.首先下载jdk安装包,安装的时候会有两个文件安装,一个是jdk一个是jre建议两个文件不要安装在一个目录下 2.安装jdk后面就是配置环境变量,path和classpath,path要在用户变量中 ...
- [新手教程]申请https泛域名解析
前置准备 教程开始,我们默认相信小伙伴们对基本的域名购买及解析有了一定的认识和实践 一个正常的域名 一台公网服务器 域名解析操作 如:现在我们要设置frps的泛域名解析 设置二级域名 frp.xx.c ...
- 风炫安全web安全学习第三十一节课 命令执行以及代码执行演示
风炫安全web安全学习第三十一节课 命令执行以及代码执行演示 参考: http://blog.evalshell.com/2020/12/20/风炫安全web安全学习第三十一节课-命令执行以及代/
- 离散傅里叶变换DFT入门
网上对于傅里叶变换相关的文章很多(足够多),有的是从物理相关角度入场,有的从数学分析角度入场.对于有志学习相关概念的同学还是能够很好的理解的. 数学包括三大块:代数学.几何.数学分析.前两块我们在中学 ...
- LeetCode116 每个节点的右向指针
给定一个二叉树 struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *next; } 填充它的每个 ...
- SpringBoot配置文件(1)
配置文件 1.配置文件 SpringBoot使用一个全局的配置文件 application.properties application.yml 配置文件名是固定的: 他的作用是修改SpringBoo ...
- linux下的文件类型
在Linux中一切设备皆文件,首先来看一下Linux下的文件都有哪些分类,也就是文件类型 文件类型:普通文件(包括shell脚本,文档,音频,视频).目录文件.设备文件(又细分为字符设备文件和块设备文 ...
- linux系统Vsftpd搭建FTP
安装vsftp 使用yum命令安装vsftp #yum install vsftpd -y 添加ftp帐号和目录 先检查下nologin的位置,通常在/usr/sbin/nologin下 (*no ...
- 【排序基础】1、选择排序法 - Selection Sort
文章目录 选择排序法 - Selection Sort 为什么要学习O(n^2)的排序算法? 选择排序算法思想 操作:选择排序代码实现 选择排序法 - Selection Sort 简单记录-bobo ...