例说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浅拷贝) 类对象之间的初始化是由类的拷贝构造函数完毕的.它是一种特殊的构造函数,它的作用是用一个已知的对象来初始化还有一个对象.假设在类中没有显式地声明一个拷贝构造函数.那么, ...
随机推荐
- Css3动画库收集
1.animate.css – 齐全的CSS3动画库 http://www.dowebok.com/98.html 2.Angular官方动画库 http://augus.github.io/ngAn ...
- eclipse和android studio导入工程的错误
eclipse中导入工程,需要注意导入的工程是什么,android 工程和java工程是有区别的.如果导入错误了,调起来也比较麻烦.因为入口错了呀. 特别在android studio工程,从其它人的 ...
- Dojo Widget中的全局变量
转自http://blog.163.com/mqsy_yj/blog/static/2940499220121014115338929/ 前期设计了一个清除widget的功能,虽然可以从html文件中 ...
- EF中使用语句 或存储过程 查询(转)
EF中使用语句 或存储过程 查询 1.无参数查询 var model = db.Database.SqlQuery("select* from UserInfoes ").ToLi ...
- 四、使用Maven和使用Eclipse构建javaWeb项目
环境前边已经搭建过了,我们就再弄了. 1.使用Maven构建javaWeb项目 (1).键入以下命令: $ mvn archetype:generate -DgroupId=com.holytax.w ...
- ios专题 -block用法
what is block Blocks are a language-level feature added to C, Objective-C and C++, which allow you t ...
- Less 官方文档学习笔记
LESS 是css的一种扩展,它的编辑器是基于node.js 的less.js,将less文件编译成css文件(可压缩). 其中的概念: 变量:定义变量来代替某个值,只能编译一次,本质是“常量”.例如 ...
- Flask,HelloWorld
Flask,HelloWorld # -*- coding:utf-8 -*- ''' Created on 2015年10月19日 ''' from flask import Flask app = ...
- 重新设置MySQL的root密码
1.首先确认服务器出于安全的状态,也就是没有人能够任意地连接MySQL数据库. 因为在重新设置MySQL的root密码的期间,MySQL数据库完全出于没有密码保护的 状态下,其他的用户也可以任意地登录 ...
- Docker之配置Centos_ssh
写Dockerfile配置文件 #DockerfileFROM centos:6 #以下命令用在什么镜像中MAINTAINER cuizhipeng <cuizhipeng@126.com&g ...