Deep copy and shallow copy under.net platform

  • 2020-10-23 20:56:41
  • OfStack

Basic concepts:

Shallow copy: The field of an object is copied, and the object referenced by the field is not copied. The copied object and the original object are only referenced by different names, but they share one entity. A change to one object affects another. Most reference types implement a shallow copy. Assignment between reference type objects is to copy one copy of the reference address of the object, while pointing to the same object instance.

Deep copy: When a subsegment of an object is copied and the object referenced by the field is copied. The deep copy creates the structure of the entire source object. The copy object and the original object are independent of each other, do not share any instance data, and modifying one object does not affect another object. An assignment between value types that performs a deep copy.

Reference code for basic concepts:


class Program
    {
        static void Main(string[] args)
        {
            Student s1 = new Student("li", 23);
            // Shallow copy 
            Student s2 = s1;
            s2.Age = 27;
            s1.ShowInfo();//li's age is 27
            // Deep copy 
            int i = 12;
            int j = i;
            j = 22;
            Console.WriteLine(i);//12
            Console.Read();
        }
    }
    class Student
    {
        public string Name;
        public int Age;
        public Student(string name, int age)
        {
            Name = name;
            Age = age;
        }
        public void ShowInfo()
        {
            Console.WriteLine("{0}'s age is {1}", Name, Age);
        }
    }

Analysis:

In the above example, instance s2 made a shallow copy of s1, making changes to the Age field in s2, which in turn affected the Age field in instance s1.

In the deep copy, there is only a simple assignment between value types. Changes to "j" do not change the value of "i".

Depth copy implementation:


public object Clone()
{
return this.MemberwiseClone();
}

MemberwiseClone: Create a copy of the shallow table. The procedure is to create a new object and then copy the non-static fields of the current object to the new object. Copy the field bit by bit if it is a value type, and copy the reference but not the reference object if the field is a reference type.

Reference code:


class Program
    {
        static void Main(string[] args)
        {
            ClassA ca = new ClassA();
            ca.value = 88;
            ClassA ca2 = new ClassA();
            ca2 = (ClassA)ca.Clone();
            ca2.value = 99;
            Console.WriteLine(ca.value + "-----" + ca2.value);//88---99
            ClassB cb = new ClassB();
            cb.Member.value = 13;
            ClassB cb2 = (ClassB)cb.Clone();
            cb2.Member.value = 7;
            Console.WriteLine(cb.Member.value.ToString() + "------" + cb2.Member.value.ToString());// Shallow copy: 7---7       Deep copy: 13----7           
            Console.Read();
        }
    }
    public class ClassA : ICloneable
    {
        public int value = 0;
        public object Clone()
        {
            return this.MemberwiseClone();
        }
    }
    public class ClassB : ICloneable
    {
        public ClassA Member = new ClassA();
        public object Clone()
        { 
            // Shallow copy 
            return this.MemberwiseClone();
            // Deep copy 
            ClassB obj = new ClassB();
            obj.Member = (ClassA)Member.Clone();
            return obj;
        }
    }

Analysis:

In the above example, ca2 copies the ca object, implementing a deep copy. The result is as shown in the code: changes to the ca2 median value type field do not affect the fields in ca.

In class ClassB, the reference to the type member Member is only a shallow copy if implemented using the clone method in ClassA, as can be seen in the reference code above: changes to member for cb2 affect cb. However, when using deep copy in the reference code, changes to member for cb2 do not affect cb.

Find a comprehensive example on the Internet, with a comparative copy to explain the depth:

Example 1:


public class Sex:ICloneable 
    {
        private string _PSex;
        public string PSex
        {
            set{ _PSex = value;}
            get { return _PSex; }
        }
        //public object Clone()
        //{
        //    return this.MemberwiseClone();
        //}
    }
    public class Person : ICloneable
    {
        private Sex sex = new Sex();
        public int aa = 3;
        public string pSex
        {
            set { sex.PSex = value; }
            get { return sex.PSex; }
        }
        private string _PName;
        public string PName
        {
            set { this._PName = value; }
            get { return this._PName; }
        }
        public void ShowPersonInfo()
        {
            Console.WriteLine("-------------------------");
            Console.WriteLine("Name:{0} Sex:{1}", _PName, this.pSex);
            Console.WriteLine("-------------------------");
            Console.WriteLine(this.aa);
        }
        // Shallow copy 
        public object Clone()
        {
            return this.MemberwiseClone();
        }
        // Deep copy 
        public object DeepClone()
        {
            Person newP = new Person();
            newP.PName = this._PName;
            newP.pSex = this.pSex;
            return newP;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(" The original object :");
            Person p = new Person();
            p.PName = "Lee";
            p.pSex = " male ";
            p.ShowPersonInfo();// Original object: lee  male  3
            // Shallow copy         
            Person copy = (Person)p.Clone();
            // Deep copy 
            Person dcopy = (Person)p.DeepClone();
            Console.WriteLine(" The original object after modification :");
            p.PName = "Zhao";
            p.pSex = " female ";
            p.aa = 1;
            p.ShowPersonInfo();//zhao  female  1
            Console.WriteLine(" Modified shallow copy object: ");
            copy.ShowPersonInfo();//lee  female  3
            Console.WriteLine(" Modified deep copy object: ");
            dcopy.ShowPersonInfo();//lee  male  3
            Console.WriteLine(" Direct copy object: ");
            Person PP = p;
            PP.ShowPersonInfo();//zhao  female  1
            Console.ReadLine();
        }
    }

Analysis:

First of all, it should be noted that in the above example, in class Sex, the addition of the Clone method has no effect on the result of the operation in the instance.

In class Person, the reference type is the PName field of string, the reference type is the pSex field, and the value type is aa.

Initial value: lee male 3 (copy in depth first)

Modified value: zhao female 1

Shallow copy value: lee female 3

Deep copy value: lee male 3

Direct copy value: Zhao Nv 1

Results: The above can be said to be a summary and comparison of several types often encountered in shallow copy. I believe that we can learn some knowledge after understanding.

Example 2:


class Program
    {
        static void Main(string[] args)
        {
            int[] numbers = { 2, 3, 4, 5 };
            int[] numbersCopy = new int[5];
            numbers.CopyTo(numbersCopy, 0);
            numbersCopy[2] = 0;
            int[] numbers1 = { 2, 3, 4, 5 };
            int[] numbersClone1 = (int[])numbers1.Clone();
            numbersClone1[2] = 0;
            Console.Write(numbers[2] + "---" + numbersCopy[2]);//4---0
            Console.Write(numbers1[2] + "---" + numbersClone1[2]);//4--0

            // The copy of the array, which is passed by reference, points to the same 1 An address 
            int[] numbers2 = { 2, 3, 4, 5 };
            int[] numbers2Copy = numbers2;
            numbers2Copy[2] = 0;
            Console.Write(numbers2[2]);//0
            Console.Write(numbers2Copy[2]);//0
            Console.Read();
        }
    }

Don't do the analysis for a while.


Related articles: