zoukankan      html  css  js  c++  java
  • .NET基础之深度复制和浅度复制

    之前一直没有搞清楚深度复制和浅度复制的区别到底在哪里,今天彻底把这个东西弄懂了,写出来与到家共勉。

    如果大家不懂值类型和引用类型的区别,请先看http://www.cnblogs.com/Autumoon/archive/2008/08/18/1270685.html,本来想自己写的,但刚好看到了这篇写的非常全面,就不自己写了。

    大家都知道Object是所有类共同的基类,其有个方法是MemberwiseClone(),其用途为

    QQ截图20141116141837我们可以通过这个方法来达到浅度复制的效果。

    下面我们通过一个例子来阐述一下浅度复制,其与深度复制的区别在什么地方:

    public class Content
        {
            public int Val;
        }
        public class Cloner
        {
            public Content MyContent = new Content();
    
            public Cloner(int newVal)
            {
                MyContent.Val = newVal;
            }
            public object GetCopy()
            {
                return MemberwiseClone();
            }
        }

    在这里我们有两个类,一个Content类,只有一个为值类型int的Val,还有个类是一个Cloner类,其有一个Content类型的成员,然后有个构造函数可以初始化成员,最后有一个GetCopy的方法,通过MemberwiseClone方法来复制自己。

    下面我们通过一段代码来调用Cloner类:

    static void Main(string[] args)
            {
                Cloner source = new Cloner(10);
                Cloner target = (Cloner)source.GetCopy();//返回的是一个Object类型 需要做类型转换.
                Console.WriteLine("target.MyContent.Val = {0}", target.MyContent.Val);
                source.MyContent.Val = 15;
                Console.WriteLine("target.MyContent.Val = {0}", target.MyContent.Val);
                Console.ReadKey();
            }

    结果是:

    Copy

    我们可以看到我们通过GetCopy()函数复制类source给target,但是当我们改变source的时候,source输出的值也跟着改变。由此我们可以得出,我们通过MemberwiseClone()复制的只是引用,即source和target的MyContent是相同的对象实例。这就是浅度复制,那我们如何实现深度复制呢,在.NET Framework中,给我们提供了ICloneable接口。

    首先我们看下ICloneable接口:

    // 摘要:
        //     支持克隆,即用与现有实例相同的值创建类的新实例。
        [ComVisible(true)]
        public interface ICloneable
        {
            // 摘要:
            //     创建作为当前实例副本的新对象。
            //
            // 返回结果:
            //     作为此实例副本的新对象。
            object Clone();
        }

    在上面那个例子中,我们只需要修改一些代码就可以了:

    public class Cloner:ICloneable
        {
            public Content MyContent = new Content();
    
            public Cloner(int newVal)
            {
                MyContent.Val = newVal;
            }
            //public object GetCopy()
            //{
            //    return MemberwiseClone();
            //}
            public object Clone()
            {
                Cloner cloned = new Cloner(MyContent.Val);
                return cloned;
            }
        }

    为了做区别我把之前的代码放在上面,注释了的代码就是浅度复制,后面的为深度复制,我们看到差别在于用本实例的MyContent.Val重新生成了实例返回给目标,测试结果为:

    QQ截图20141116144216

    这里如果MyContent的成员不是一个值类型,那么我们还需要进行深度,像下面一样:

    public object Clone()
            {
                Cloner cloned = new Cloner();
                cloned.MyContent = MyContent.Clone();
                return cloned;
            }

    深度复制和浅度复制就是这样,关键是创建一个新的对象实例返回去,而不是把原来的对象实例返回回去。大家懂了吗?

  • 相关阅读:
    审计 6 SSRF和任意文件读取
    审计5 文件包含漏洞
    审计4 XSS
    owasp Top 10 个人总结
    审计3(由安装引起的服务器沦陷)
    python批量爆破后台目录脚本
    python批量检测注入点脚本
    对VAuditDemo的审计<2>
    工作总结(一)
    使用vue upload 标签上传图片后端MultipartFile 为null
  • 原文地址:https://www.cnblogs.com/laoqi/p/4101427.html
Copyright © 2011-2022 走看看