• 深拷贝和浅拷贝的区别


    浅拷贝一般是用的这个方法  MemberwiseClone()
    
    在拷贝的时候主要是关心值和引用两者拷贝后的区别,这个区别也是深拷贝和浅拷贝的区别
    
    
    下面这个类中就使用了这个方法
    
    
             class DemoClass : ICloneable
        {
            public int intValue = 1;
            public string strValue = "1";
            public PersonEnum pEnum = PersonEnum.EnumA;
            public PersonStruct pStruct = new PersonStruct();
            public Person pClass = new Person("1");
    
            public int[] pIntArray = new int[] { 1 };
            public string[] pArray = new string[] { "1" };
            #region ICloneable 成员
    
             public DemoClass()
            {
                pStruct.StructValue = 1;
            }
            public object Clone()
            {
               return this.MemberwiseClone();
            }
            #endregion
        }
    
        class Person
        {
            public string Name;
    
            public Person(string name)
            {
                Name = name;
            }
    
        }
        public enum PersonEnum
        {
            EnumA=1,
            EnumB=2
        }
        public struct PersonStruct
        {
          public  int StructValue;
        }

    说明:

    
    
    这里的示例,我用上了:
    int
    string
    int[]
    string[]
    enum
    struct
    class
    然后接下来会产生实例A和克隆实例B。
    接着改变B的值,看A的值会不会被改变。
    
    
    
    
    

    接下我们看main方法

     static void Main(string[] args)
            {
                Demo();
            }
            public static void Demo()
            {
                DemoClass A = new DemoClass();
                DemoClass B = (DemoClass)A.Clone();
                B.intValue = 2;
                Write(string.Format("        int->[A:{0}] [B:{1}]", A.intValue, B.intValue));
                B.strValue = "2";
                Write(string.Format("     string->[A:{0}] [B:{1}]", A.strValue, B.strValue));
                B.pEnum = PersonEnum.EnumB;
                Write(string.Format("       Enum->[A:{0}] [B:{1}]", (int)A.pEnum, (int)B.pEnum));
                B.pStruct.StructValue = 2;
                Write(string.Format("     struct->[A:{0}] [B:{1}]", A.pStruct.StructValue, B.pStruct.StructValue));
                B.pIntArray[0= 2;
                Write(string.Format("   intArray->[A:{0}] [B:{1}]", A.pIntArray[0], B.pIntArray[0]));
                B.pStringArray[0= "2";
                Write(string.Format("stringArray->[A:{0}] [B:{1}]", A.pStringArray[0], B.pStringArray[0]));
                B.pClass.Name = "2";
                Write(string.Format("      Class->[A:{0}] [B:{1}]", A.pClass.Name, B.pClass.Name));
                System.Console.Read();
            }
            static void Write(string msg)
            {
                System.Console.WriteLine(msg);
            }

    说明:

    我们通过改变B实例的值,然后打印出A和B的值看结果。

    打印结果如下:

    从最后输出的结果我们得知:

    对于内部的Class的对象和数组,会Copy地址一份。[从而改变B时,A也被改变了]
    而对于其它内置的int/string/Enum/struct/object类型,则进行值copy。

    最后,我试着百度寻找浅拷贝最原生的定义,浅搜了一下找不到,那这个定义,就留给读者解答一下了。

    接着,我顺手比较了一下浅拷贝和深拷贝的性能测试:

    先在DemoClass加入一个函数:

    public object CloneNew()
    {
       return new DemoClass();
    }

    接着我们写示例代码比较:

    ExpandedBlockStart.gif
            public static void Compare()
            {
                DemoClass baseClass = new DemoClass();

                DateTime start = DateTime.Now;
                for (int i = 0; i < 1000000; i++)
                {
                    DemoClass newClass = (DemoClass)baseClass.Clone();
                }
                TimeSpan ts = DateTime.Now - start;
                System.Console.WriteLine("浅拷贝:" + ts.Ticks);

                DateTime start2 = DateTime.Now;
                for (int j = 0; j < 1000000; j++)
                {
                    DemoClass newClass = (DemoClass)baseClass.CloneNew();
                }
                TimeSpan ts2 = DateTime.Now - start2;
                System.Console.WriteLine("深拷贝:" + ts2.Ticks);

               
                System.Console.Read();
            }

    最后得出结果:

    看来直接用浅拷贝性能还不如直接返回一个new的对象。
    同样的,用克隆返回object最后还得对类型转换进行一些开销,教人情何以堪!
     
     
     
  • 相关阅读:
    TomCat 的 Jenkins 报错:反向代理设置有误
    【Django】如何在类视图、普通视图单独不做CSRF校验
    【Django】HTML如何显示富文本内容
    Djaong 运行报错:ValueError: Unable to configure handler 'default'
    Windows 环境使用 Xshell 连接 VMware 虚拟机上的 CentOS 系统
    【我的青春我做主】让自己的心境安宁
    Django 使用 Nginx + uWSGI 启动
    Django_文件下载
    追梦何须要问成败,只管向前吧
    PyCharm:设置py文件头部信息
  • 原文地址:https://www.cnblogs.com/zhengwei-cq/p/9167708.html
Copyright © 2020-2023  润新知