解析C#对象中的深浅拷贝_第1页
解析C#对象中的深浅拷贝_第2页
解析C#对象中的深浅拷贝_第3页
解析C#对象中的深浅拷贝_第4页
解析C#对象中的深浅拷贝_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

解析解析 C 对象中的深对象中的深 浅拷贝浅拷贝 2010 11 09 15 23 21 0 来源 博客网 作者 小 R 关键词 关键词 C 深拷贝 浅拷贝 C 中有两种类型变量 一种 是值类型变量 一种是引用类型变量 对于值类型变量 深拷贝和前拷贝都是通过赋值操作符号 实现 其效果一致 将对象中的值类型的字段拷 贝到新的对象中 这个很容易理解 本文重点讨论引用类型变量的拷贝机制和实现 C 中引用类型对象的 copy 操作有两种 浅拷贝 影子克隆 shallow copy 只复制对象的值类型字段 对象的引用类型 仍属于 原来的引用 深拷贝 深度克隆 不仅复制对象的值类型字段 同时也复制原对象中的对象 就是说完全是新对象产生的 浅拷贝和深拷贝之间的区别 浅拷贝是指将对象中的数值类型的字段拷贝到新的对象 中 而对象中的引用型字段则指复制它的一个引用到目标对象 注意 string 类型有点特殊 对于浅拷贝 类值类型对象进行处理 浅拷贝的实现浅拷贝的实现 使用 Object 类 MemberwiseClone 实现 MemberwiseClone 创建当前 Object 的浅表副本 MemberwiseClone 方法创建一个浅表副本 方法是创建一个新对象 然后将当前 对象的非静态字段复制到该新对象 如果字段是值类型的 则对该字段执行逐位复制 如 果字段是引用类型 则复制引用但不复制引用的对象 因此 原始对象及其复本引用同一对 象 代码实现如下 public class Person public int Age get set public string Address get set public Name Name get set public object Clone return this MemberwiseClone public class Name public Name string frisName string lastName FristName frisName LastName lastName public string FristName get set public string LastName get set 赋值操作 VS 使用 Object 类 MemberwiseClone 实现 对于引用类型的变量 我们有种误解 认为赋值操作就是浅拷贝一种 其实不然 两 者有区别 浅拷贝 shallow copy 对于引用类型对象中的值类型字段进行了逐位复制 赋值运算 符只是把源对象的引用赋值给目的对象 两者引用同一个对象 浅拷贝后的对象的值类型 字段更改不会反映到源对象 而赋值运算后的对象的值类型字段更改会反映到源对象 代码 实现如下 public class Person public int Age get set public string Address get set public Name Name get set public class Name public Name string frisName string lastName FristName frisName LastName lastName public string FristName get set public string LastName get set 深拷贝实现深拷贝实现 相对于浅拷贝 是指依照源对象为原型 创建一个新对象 将当前对象的所有字段进行 执行逐位复制并支持递归 不管是是值类型还是引用类型 不管是静态字段还是非静态字 段 在 C 中 我们们有三种方法实现深拷贝 实现 ICloneable 接口 自定义拷贝功能 ICloneable 接口 支持克隆 即用与现有实例相同的值创建类的新实例 ICloneable 接口包含一个成员 Clone 它用于支持除 MemberwiseClone 所提供 的克隆之外的克隆 Clone 既可作为深层副本实现 也可作为浅表副本实现 在深层副本 中 所有的对象都是重复的 而在浅表副本中 只有顶级对象是重复的 并且顶级以下的对 象包含引用 结果克隆必须与原始实例具有相同的类型或是原始实例的兼容类型 代码实现如下 Code public class Person ICloneable public int Age get set public string Address get set public Name Name get set public object Clone Person tem new Person tem Address this Address tem Age this Age tem Name new Name this Name FristName this Name LastName return tem public class Name public Name string frisName string lastName FristName frisName LastName lastName public string FristName get set public string LastName get set 大家可以看到 Person 类继承了接口 ICloneable 并手动实现了其 Clone 方法 这是 个简单的类 试想一下 如果你的类有成千上万个引用类型成员 当然太夸张 几十个还是有的 这是不是份很恐怖的劳力活 序列化 反序列化类实现 不知道你有没有注意到 DataSet 对象 对于他提供的两个方法 DataSet Clone 方法 复制 DataSet 的结构 包括所有 DataTable 架构 关系 和约束 不要复制任何数据 新 DataSet 其架构与当前 DataSet 的架构相同 但是不包含任何数据 注意 如 果已创建这些类的子类 则复本也将属于相同的子类 DataSet Copy 方法复制该 DataSet 的结构和数据 新的 DataSet 具有与该 DataSet 相同的结构 表架构 关系和约束 和数据 注 意如果已创建这些类的子类 则副本也将属于相同的子类 好像既不是浅拷贝 又不是深拷贝 是不是很失望 但是两个结合起来不是我们要的深 拷贝吗 看看 DataSet 的实现 注意序列化接口 ISerializable 序列化是将对象或对象图形转换为线性字节序列 以存储或传输到另一个位置的过程 反序列化是接受存储的信息并利用它重新创建对象的过程 通过 ISerializable 接口 类可以执行其自己的序列化行为 转换为线性字节序列后并利用其重新创建对象的过程是不是和我们的深拷贝的语意 逐位复制 很相像 代码实现如下 Serializable public class Person ICloneable public int Age get set public string Address get set public Name Name get set public object Clone using MemoryStream ms new MemoryStream 1000 object CloneObject BinaryFormatter bf new BinaryFormatter null new StreamingContext StreamingContextStates Clone bf Serialize ms this ms Seek 0 SeekOrigin Begin 反序列化至另一个对象 即创建了一个原对象的深表副本 CloneObject bf Deserialize ms 关闭流 ms Close return CloneObject Serializable public class Name public Name string frisName string lastName FristName frisName LastName lastName public string FristName get set public string LastName get set 注意 通过序列化和反序列化实现深拷贝 其和其字段类型必须标记为可序列化类型 既添加特性 Attribute Serializable 通过反射实现通过反射实现 通过序列化 反序列化方式我们能比较流畅的实现深拷贝 但是涉及到 IO 操作 托管 的的环境中 IO 操作比较消耗资源 能不能有更优雅的解决方案 CreateInstance 对 利用反射特性 这个方法大家可以参考这篇博客 文章反射类的 Attribute 利用 Activator CreateInstance New 一个类出来 有点像 DataSet Clone 先获得架构 然后利用 PropertyInfo 的 SetValue 和 GetValue 方法 遍历的方式进行值填充 代码实现如下 public class Person private List friends new List public string Firstname get set public stri

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论