zoukankan      html  css  js  c++  java
  • 浅谈对对象clone的理解

    对象clone是一非常方便且有用的方法,在对数据的处理,尤其是大数据量的处理时,更觉可贵。

    现谈下本人对对象clone的理解。

    CLONE分为两种:深度clone(deep clone) 和 浅度clone(shallow clone). 都是 创建一与原对象具有相同类型的新实例。

    但是有区别的,其创建过程不完全相同:

    浅度clone(shallow clone): 创建与原始对象具有相同类型的新实例,然后复制原始对象的非静态字段(静态字段不属于类实例)。

         如果字段是值类型的,则对该字段 执行逐位复制。如果字段是引用类型,则复制该引用但不复制被引用的对象。

    深度clone(deep clone): 创建与原始对象具有相同类型的新实例,然后复制原始对象的非静态字段(静态字段不属于类实例)。

         如果字段是值类型的,则对该字段 执行逐位复制。如果字段是引用类型,则复制该引用指向的实例而非复制该引用。

    注意以上着为橙色的字体,区别就在此。可见,

    相同点: clone所得对象与原对象的reference是不同的(因为不是一个实例),Equals的结果是false的(前提是没有override object's   Equals方法)。

    区别: shallow clone的对象,其2级/3级/../n级引用对象的reference是相同的(因为是复制的reference,都指向同一实例),所以Equals(前提是没有override object's Equals方法)其对象关系网中的引用对象,是true的。

    而deep clone的对象,是递归复制其对象关系网中的对象实例(而非引用),则Equals肯定是false的。

    注意点: 无论deep or shallow clone,其进行的都是复制,而非new工作,所以类的初始化过程在clone中是不会产生的,即:成员初始化、类初始化等等,它仅是对已有对象的一个copy的,并将copy所得对象的heap address 赋值给新的reference的。

    DEMO之:有对象X,A,B,C,X引用了A、B,A引用了C,伪代码演示如下:

    shallow clone
    deep clone

    .NET中,Object默认所带的protected MemberwiseClone()方法,就是一个 shallow clone,要实现deep clone,

    则要自己来实现的。.NET提供了一个接口IClone,是用来支持对象的deep clone的,但归根接底,还是要我们自己来实现clone()方法的,也就是说,实现该方法的不一定就是deep clone,甚至都不是clone,要看你是如何实现的,它仅是一个约束,要求你应该去这么做,但你不这么做,它也没办法(不过你不这么做,也只会给自己在使用中带来麻烦的)。

    比如:我们看下.NET自己所实现IClone的几个类:Array 和 ArrayList,前者是shallow clone,后者则是deep clone的。

    Array.Clone

     

    ArrayList.Clone

    这里提供一个利用序列化进行deep clone方法的实现(前提,对象关系网中的对象必须是可序列化Serializable的)

    Serializable deep clone

  • 相关阅读:
    移动端链接、点击事件、输入框去除背景高亮
    Quartz.Net与MVC结合定时任务
    Win10上使用SVN遇到的一些问题
    Win7上的ASP.NET MVC3项目在Win10上运行的一个坑
    《SQL必知必会》学习笔记(二)
    《SQL必知必会》学习笔记(一)
    数据库知识总结(表结构操作)
    搭建三层架构(ASP.NET MVC+EF)
    python线程中的全局变量与局部变量
    ADO.NET Entity Framework学习笔录(一)
  • 原文地址:https://www.cnblogs.com/FallingAutumn/p/1256052.html
Copyright © 2011-2022 走看看