文章转自:http://www.cnblogs.com/zhangji/archive/2011/02/23/1961897.html

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

为了实现深度复制,我们就必须遍历有相互引用的对象构成的图,并需要处理其中的循环引用结构。这无疑是十分复杂的。幸好借助.Net的序列化和反序列化机制,可以十分简单的深度Clone一个对象。原理很简单,首先将对象序列化到内存流中,此时对象和对象引用的所用对象的状态都被保存到内存中。.Net的序列化机制会自动处理循环引用的情况。然后将内存流中的状态信息反序列化到一个新的对象中。这样一个对象的深度复制就完成了。在原型设计模式中CLONE技术非常关键。

下面的代码就是演示这个问题:

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary; namespace CloneDemo
{
[Serializable]
class DemoClass
{
public int i = 0;
public int[] iArr = { 1, 2, 3 }; public DemoClass Clone1() //浅CLONE
{
return this.MemberwiseClone() as DemoClass;
} public DemoClass Clone2() //深clone
{
MemoryStream stream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, this);
stream.Position = 0;
return formatter.Deserialize(stream) as DemoClass;
}
} class Program
{
static void Main(string[] args)
{
DemoClass a = new DemoClass();
a.i = 10;
a.iArr = new int[] { 8, 9, 10 };
DemoClass b = a.Clone1();
DemoClass c = a.Clone2(); // 更改 a 对象的iArr[0], 导致 b 对象的iArr[0] 也发生了变化 而 c不会变化
a.iArr[0] = 88; Console.WriteLine("MemberwiseClone");
Console.WriteLine(b.i);
foreach (var item in b.iArr)
{
Console.WriteLine(item);
} Console.WriteLine("Clone2");
Console.WriteLine(c.i);
foreach (var item in c.iArr)
{
Console.WriteLine(item);
} Console.ReadLine();
}
}
}

MemberwiseClone和DeepClone的更多相关文章

  1. Equals Finalize GetHashCode GetType MemberwiseClone ReferenceEquals ToString String.IsInterned

    参考资料: http://blog.csdn.net/afgasdg/article/details/6889383 http://www.cnblogs.com/skyivben/archive/2 ...

  2. C#之MemberwiseClone与Clone

    MemberwiseClone 方法创建一个浅表副本,具体来说就是创建一个新对象,然后将当前对象的非静态字段复制到该新对象.如果字段是值类型的,则对该字段执行逐位复制.如果字段是引用类型,则复制引用但 ...

  3. MyDAL - 引用类型对象 .DeepClone() 深度克隆[深度复制] 工具 使用

    索引: 目录索引 一.API 列表 .DeepClone() 用于 Model / Entity / ... ... 等引用类型对象的深度克隆 特性说明 1.不需要对对象做任何特殊处理,直接 .Dee ...

  4. js 深度复制deepClone

    function isObject(obj) { return typeof obj === 'object' && obj != null; } const deepClone =( ...

  5. C# 深浅复制 MemberwiseClone(转载)

    最近拜读了大话设计模式:原型模式,该模式主要应用C# 深浅复制来实现的!关于深浅复制大家可参考MSDN:https://docs.microsoft.com/zh-cn/dotnet/api/syst ...

  6. C# 深浅复制 MemberwiseClone

    学无止境,精益求精 十年河东,十年河西,莫欺少年穷 学历代表你的过去,能力代表你的现在,学习代表你的将来 最近拜读了大话设计模式:原型模式,该模式主要应用C# 深浅复制来实现的!关于深浅复制大家可参考 ...

  7. Object.MemberwiseClone

    [Object.MemberwiseClone] Creates a shallow copy of the current Object. protected object MemberwiseCl ...

  8. C#设计模式(6)——原型模式(Prototype Pattern) C# 深浅复制 MemberwiseClone

    C#设计模式(6)——原型模式(Prototype Pattern)   一.引言 在软件系统中,当创建一个类的实例的过程很昂贵或很复杂,并且我们需要创建多个这样类的实例时,如果我们用new操作符去创 ...

  9. 浅谈C#中的深拷贝(DeepCopy)与浅拷贝(MemberwiseClone)

    场景:MVVM模式中数据双向绑定,想实现编辑.保存.撤销操作时也双向绑定了,不能实现撤销操作. 后来通过搜索找到了继承IEditableObject接口实现撤销操作,但是对其中使用了Memberwis ...

随机推荐

  1. 05传智_jbpm与OA项目_部门模块中增加部门的jsp页面增加一个在线编辑器功能

    这篇文章讲的是在线编辑器功能,之前的部门模块中,增加部门的功能jsp页面起先是这么做的.

  2. CodeGenerator.cs

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace CiCe ...

  3. Mybatis.Net 整合 ODP.NET Managed

    初步接触MyBatis.Net的朋友,请先移步 MyBatis.Net 学习手记 1. 项目中先添加Oracle.ManagedDataAccess.dll程序集引用 2. MyBatis.Net 中 ...

  4. 数据字典生成工具之旅(4):NPOI操作EXECL

    这篇会介绍NPOI读写EXECL,读写EXECL的组件很多,可以使用微软自己的COM组件EXECL.exe读写,不过这种方式限制很大. 1:客户环境必须装Office(虽然现在机子上不装Office的 ...

  5. MySql 中文乱码排查解决方案

    MySQL会出现中文乱码的原因不外乎下列几点: server本身设定问题,例如还停留在latin1 table的语系设定问题(包含character与collation) 客户端程式(例如php)的连 ...

  6. SQLServer(MSSQL)、MySQL、SQLite、Access相互迁移转换工具 DB2DB v1.1

    最近公司有一个项目,需要把原来的系统从 MSSQL 升迁到阿里云RDS(MySQL)上面.为便于测试,所以需要把原来系统的所有数据表以及测试数据转换到 MySQL 上面.在百度上找了很多方法,有通过微 ...

  7. ASP.NET 系列:单元测试之StructureMap

    ASP.NET使用StructureMap等依赖注入组件时最重要就是EntityFramework的DbContext对象要保证在每次HttpRequest只有一个DbContext实例,这里将使用第 ...

  8. meta标签大全

    meta标签大全 <!--     x-ua-compatible(浏览器兼容模式)     仅对IE8+以效     告诉浏览器以什么版本的IE的兼容模式来显示网页     <meta ...

  9. Tensorflow学习笔记2:About Session, Graph, Operation and Tensor

    简介 上一篇笔记:Tensorflow学习笔记1:Get Started 我们谈到Tensorflow是基于图(Graph)的计算系统.而图的节点则是由操作(Operation)来构成的,而图的各个节 ...

  10. .Net分布式异常报警系统-服务端Service

    服务端的2个Service 1. HandleService: 从Redis中获取异常信息, 入库并发送通知到相关责任人.  2. HealthyCheckService: 对站点指定页面进行模拟访问 ...