例说C#深拷贝与浅拷贝
一开始,先对C#深拷贝与浅拷贝知识做个简单的总结。
无论是浅拷贝与深拷贝,C#都将源对象中的所有字段复制到新的对象中。不过,对于值类型字段,引用类型字段以及字符串类型字段的处理,两种拷贝方式存在一定的区别(见下表)。
下面给出完整的演示代码。
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary; namespace DeepCloneExp
{
class Program
{
static void Main(string[] args)
{
Person p = new Person() { Name="tiana0",Age=20,Job=new Job(){JobName="Coder"} }; Person p1 = p.ShallowClone();
Person p2 = p.DeepClone(); Console.WriteLine("p浅拷贝-->p1;p深拷贝-->p2"); Console.WriteLine("p修改前:p.Name={0},p.Age={1},p.Job.JobName={2}", p.Name, p.Age, p.Job.JobName);
Console.WriteLine("p修改前:p1.Name={0},p1.Age={1},p1.Job.JobName={2}", p1.Name, p1.Age, p1.Job.JobName);
Console.WriteLine("p修改前:p2.Name={0},p2.Age={1},p2.Job.JobName={2}", p2.Name, p2.Age, p2.Job.JobName); //修改p的所有字段值
p.Name = "tiana10000";
p.Age = 28;
p.Job.JobName = "Manager"; Console.WriteLine(); Console.WriteLine("p修改后:p.Name={0},p.Age={1},p.Job.JobName={2}", p.Name, p.Age, p.Job.JobName);
Console.WriteLine("p修改后:p1.Name={0},p1.Age={1},p1.Job.JobName={2}", p1.Name, p1.Age, p1.Job.JobName);
Console.WriteLine("p修改后:p2.Name={0},p2.Age={1},p2.Job.JobName={2}", p2.Name, p2.Age, p2.Job.JobName);
}
} [Serializable]
class Person:ICloneable
{
public int Age { get; set; } //值类型字段
public string Name { get; set; } //字符串
public Job Job { get; set; } //引用类型字段 //深拷贝
public Person DeepClone()
{
using (Stream objectStream = new MemoryStream())
{
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(objectStream,this);
objectStream.Seek(0, SeekOrigin.Begin);
return formatter.Deserialize(objectStream) as Person;
}
} public object Clone()
{
return this.MemberwiseClone();
} //浅拷贝
public Person ShallowClone()
{
return this.Clone() as Person;
}
} [Serializable]
public class Job
{
public string JobName { get; set; }
public override string ToString()
{
return this.JobName;
}
}
}
运行程序,得到以下结果:
先来看看结果,很明显,当源对象改变时,副本只有浅拷贝这种情况下的引用类型字段的值会一起变化,与前面给出的结论一致(不记得的话,麻烦再看一下表格)。
对于演示代码,仅补充说明: Person 类与Job类均需添加标志[Serializable],否则运行时会报错。
好了,就扯到这里了。
例说C#深拷贝与浅拷贝的更多相关文章
- 设计模式_11_原型模式(prototype)深拷贝、浅拷贝
设计模式_11_原型模式(prototype) 浅拷贝: package designPatternOf23; /** * 定义:用原型实例,指定创建对象的种类,并通过拷贝这些原型创建新的对象 * P ...
- .net平台下深拷贝和浅拷贝
在.net类库中,对象克隆广泛存在于各种类型的实现中,凡是实现了ICloneable接口的类型都具备克隆其对象实例的能力.所以本文讲述的深拷贝和浅拷贝也是在实现ICloneable接口的基础上进行的. ...
- 理解python可变类型vs不可变类型,深拷贝vs浅拷贝
核心提示: 可变类型 Vs 不可变类型 可变类型(mutable):列表,字典 不可变类型(unmutable):数字,字符串,元组 这里的可变不可变,是指内存中的那块内容(value)是否可以被改变 ...
- C++ Primer笔记9_构造函数_拷贝构造(深拷贝与浅拷贝)
1.构造函数: >构造函数是一个特殊的.与类同名的成员函数,用于给每一个成员设置适当的初始值. >构造函数不能有返回值,函数名与类名同样. >缺省构造函数时,系统将自己主动调用该缺省 ...
- java克隆之深拷贝与浅拷贝
版权声明:本文出自汪磊的博客,转载请务必注明出处. Java深拷贝与浅拷贝实际项目中用的不多,但是对于理解Java中值传递,引用传递十分重要,同时个人认为对于理解内存模型也有帮助,况且面试中也是经常问 ...
- 从JS的深拷贝与浅拷贝到jq的$.extend()方法
一.堆内存与栈内存 堆和栈都是内存中划分出来的用来存储的区域,栈为自动分配的内存空间,它由系统自动释放,堆为动态分配的内存,大小不定也不会自动释放. 二.js基本数据类型与引用类型的不同 基本数据类型 ...
- 浅谈.net平台下深拷贝和浅拷贝
在.net类库中,对象克隆广泛存在于各种类型的实现中,凡是实现了ICloneable接口的类型都具备克隆其对象实例的能力.所以本文讲述的深拷贝和浅拷贝也是在实现ICloneable接口的基础上进行的 ...
- iOS深拷贝与浅拷贝
概念 对象拷贝有两种方式:浅复制和深复制.顾名思义,浅复制,并不拷贝对象本身,仅仅是拷贝指向对象的指针:深复制是直接拷贝整个对象内存到另一块内存中. 如图详解:
- 拷贝构造函数(深拷贝vs浅拷贝)
拷贝构造函数(深拷贝vs浅拷贝) 类对象之间的初始化是由类的拷贝构造函数完毕的.它是一种特殊的构造函数,它的作用是用一个已知的对象来初始化还有一个对象.假设在类中没有显式地声明一个拷贝构造函数.那么, ...
随机推荐
- effective c++(03)之const使用方法
char greeting[] = "hello"; char* p = greeting; //non-const pointer,non-const data const ch ...
- 百度地图API调用实例之地址标注与位置显示
之前弄了个谷歌地图API标注的调用实例,后来要求改成百度地图. 感谢主,通过网上资料(百度地图API,百度地图API详解之地图标注)收集及研究, 终于把百度地图标注和显示功能实现出来了,具体实现方法如 ...
- iOS 9 Spotlight搜索 OC版
介绍: 在WWDC 2015会议上,苹果官方公布了iOS9.除开许多新的特性和增强功能,这次升级也给了开发者们一个机会让他们的app里的内容能通过Spotlight 搜索功能被发现和使用.在iO ...
- Activiti安装
1.Activiti下载与简介 1.1 简介 Activiti项目是一项新的基于Apache许可的开源BPM平台,从基础开始构建,旨在提供支持新的BPMN 2.0标准,包括支持对象管理组(OMG), ...
- Codevs 1958 刺激
1958 刺激 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description saffah的一个朋友S酷爱滑雪,并且追求刺激(exitement, ...
- std::map的操作:插入、修改、删除和遍历
using namespace std; std::map<int,int> m_map; 1.添加 for(int i=0;i<10;i++) { m_map.insert(mak ...
- gitlab的安装以及汉化
gitlab的安装 首先在网上下载好任意版本gitlab的rpm包 推荐下面的地址: https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gi ...
- shell sort
sort is awesome! 22 hpp_national:talk:recentAtUsers-64490 23 hpp_national:talk:site_online_users:178 ...
- [C#]异步委托使用小计
APM(=Asynchronous Programming Model(=异步编程模型)) 使用 IAsyncResult 设计模式的异步操作是通过名为 Begin操作名称 和 End操作名称 的两个 ...
- ES6 语法简介
参考: http://es6.ruanyifeng.com/ 总结学习 JavaScript语言下一代标准,2015年6月正式发布. 1.let和const命令 let用作变量声明,只在代码块内有效 ...