C# 浅拷贝与深拷贝差异 解惑篇

问题源于:

今天被同事问到一个浅拷贝与深拷贝区其余问题,说其实的,记得在该校时在书在看过有关概念不一样。
只是,那时的在校生,又有多少个能对书本上那写的玩命让鬼都看不懂知识能清晰的接头啊。
工作后尽管也有用到Clone相关的内容,不过也仅是应用,基础的概念依旧没去仔细的驾驭,以于后来DataTable内部那不深不浅的架构拷贝都混和这个概念混在联名了。

一度的认为:

让得一年多之前,我去面试,被一个人问到浅拷贝与深拷贝分化,我答:浅拷贝就是拷贝就是拷贝架构,不包罗值,深拷贝就是连值也共同拷贝。
当我答出那样错误的答案时,对方并未更正,反而似乎对自身的答案还挺满意的。
嗳,面试管自己不懂还问我那题目,还让自己直接觉获得明天都是这几个样。

同事的质询:

随后同事说它的言传身教里,发现值是有拷贝的,于是自己发觉到自我的咀嚼是有问题了,我重新百度了一晃。
网上乱七杂八的答案,让我得一个歪曲的就像是正确的答案:浅拷贝不拷贝内部类的靶子

引申出的紊乱:

接着同事的问号更早已把自家引向那几个不难迷乱的荒唐深渊:浅拷贝是对引用类型拷贝地址,对值类型直接开展拷贝。

 

末段,为了回应,依然用示例来说话了:

图片 1图片 2

    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方法

图片 3图片 4

        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的值看结果。

 

打印结果如下:

图片 5

从最终输出的结果大家识破:

对此内部的Class的靶子和数组,会Copy地址一份。[故而改变B时,A也被改成了]

而对于其余内置的int/string/Enum/struct/object类型,则开展值copy。

 

终极,我试着百度搜索浅拷贝最原生的定义,浅搜了一晃找不到,那那几个概念,就留下读者解答一下了。

 

进而,我随手相比了一晃浅拷贝和深拷贝的属性测试:

先在DemoClass插手一个函数:

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

 

随后我们写示例代码比较:

图片 6图片 7

        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();
        }

 

末尾得出结果:

图片 8

如上所述直接用浅拷贝性能还不如直接重回一个new的靶子。

一样的,用克隆重临object末了还得对类型转换进行一些开支,教人情何以堪!

 

附言:

那两日刚好发烧,插了那两篇解惑篇,都是临时插进来的的题目了,接下去会继续写 CYQ.Data
轻量数据层之路
 框架 的连带文章。

 

 

相关文章