深复制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 ...
随机推荐
- Docker学习(二)- Docker 安装 Jenkins
一.拉取镜像 我这里安装的版本是2.222.3-centos,可以去这里获取你需要的版本: https://hub.docker.com/_/jenkins?tab=tags docker pull ...
- JavaScript AMD模块化规范
浏览器环境 有了服务器端模块以后,很自然地,大家就想要客户端模块.而且最好两者能够兼容,一个模块不用修改,在服务器和浏览器都可以运行. 但是,由于一个重大的局限,使得CommonJS规范不适用于浏览器 ...
- Sqoop(三)将关系型数据库中的数据导入到HDFS(包括hive,hbase中)
一.说明: 将关系型数据库中的数据导入到 HDFS(包括 Hive, HBase) 中,如果导入的是 Hive,那么当 Hive 中没有对应表时,则自动创建. 二.操作 1.创建一张跟mysql中的i ...
- LeetCode 面试题16.18.模式匹配
模式匹配 题目: 你有两个字符串,即pattern和value. pattern字符串由字母"a"和"b"组成,用于描述字符串中的模式.例如,字符串" ...
- linux + svn提交日志不能显示 日期一直都是1970-01-01
网上很多都是说将svn安装目录下的svnserve.conf文件中的anon-access 设置为read,但是 经查阅并测试, 设置为: anon-access = none 是正确的,设置成 r ...
- java之环境配置
前言:本人环境 Windows10(64位),jdk1.8.131 开发工具: IDEA 第一步: 获取JDK 方法一:推荐官网(此方法需要oracle账号,可以免费注册) 方法二:百度网盘(需要 ...
- 用js实现打印九九乘法表
用js在打印九九乘法表 思考 在学习了流程控制和条件判断后,我们可以利用js打印各式各样的九九乘法表 不管是打印什么样三角形九九乘法表,我们都应该找到有规律的地方,比如第一列的数字是什么规律,第一行的 ...
- Linux学习笔记 | 常见错误之无法获得锁
问题: 当运行sudo apt-get install/update/其他命令时,会出现如下提示: E: 无法获得锁 /var/lib/dpkg/lock-frontend - open (11: 资 ...
- C语言中左值和右值的区别(C语言学习笔记)
重要的内容要重复强调: C语言的术语Ivalue指用于识别或定位一个存储位置的标识符.( 注意:左值同时还必须是可改变的) 其实rvalue的发明完全是为了搭配lvalue , rvalue你可以理解 ...
- tf
第2章 Tensorflow keras实战 2-0 写在课程之前 课程代码的Tensorflow版本 大部分代码是tensorflow2.0的 课程以tf.kerasAPI为主,因而部分代码可以在t ...