Shallow copy or Deep copy?

前端 未结 6 858
Happy的楠姐
Happy的楠姐 2020-11-27 04:28

I am a bit new to these two methods of copying one object into the other. I am confused and unable to spot out the major difference between deep copy and shallow copy.. I ha

6条回答
  •  一生所求
    2020-11-27 05:05

    I endorse the answer from @docesam and part of the answer from @Will Yu.

    This is neither a shallow nor a deep copy, this is a reference copy. -- docesam


    ob2 = ob1; This code creates two object references that both refer to the same object. Therefore, any changes to the object made through ob1 will be reflected in subsequent uses of ob2. --Will Yu


    According to MSDN (see Remarks):

    A shallow copy of an Array copies only the elements of the Array, whether they are reference types or value types, but it does not copy the objects that the references refer to. The references in the new Array point to the same objects that the references in the original Array point to.

    Here we have two things to note:

    1. A shallow copy copies elements.
    2. A shallow copy retains the original references of the elements.

    Next, let me explain these two separately.


    To begin with, we create a Person class with a Name property:

    class Person
    {
        public string Name {get; set;}
    }
    

    Then in the Main() method, we create a Person array.

    // Create 2 Persons.
    var person1 = new Person(){ Name = "Jack" };
    var person2 = new Person(){ Name = "Amy" };
    
    // Create a Person array.
    var arrPerson = new Person[] { person1, person2 };
    

    1. A shallow copy copies elements.

    If we replace the first element in the shallow copy, the original array should not be affected:

    // Create a shallow copy.
    var arrPersonClone = (Person[]) arrPerson.Clone();
    
    // Replace an element in the shallow copy.
    arrPersonClone[0] = new Person(){Name = "Peter"};
    
    // Display the contents of all arrays.
    Console.WriteLine( "After replacing the first element in the Shallow Copy" );
    Console.WriteLine( $"The Original Array: {arrPerson[0].Name}, {arrPerson[1].Name}" );
    Console.WriteLine( $"The Shallow Copy: {arrPersonClone[0].Name}, {arrPersonClone[1].Name}" );
    

    Results:

    The Original Array: Jack, Amy
    The Shallow Copy: Peter, Amy
    

    2. A shallow copy retains the original references of the elements.

    If we change the properties of an element in the shallow copy, the original array will be affected, since the object which this element makes reference to is not copied.

    // Create a new shallow copy.
    arrPersonClone = (Person[]) arrPerson.Clone();
    
    // Change the name of the first person in the shallow copy.
    arrPersonClone[0].Name = "Peter";
    
    // Display the contents of all arrays.
    Console.WriteLine( "After changing the Name property of the first element in the Shallow Copy" );
    Console.WriteLine( $"The Original Array: {arrPerson[0].Name}, {arrPerson[1].Name}" );
    Console.WriteLine( $"The Shallow Copy: {arrPersonClone[0].Name}, {arrPersonClone[1].Name}" );
    

    Results:

    The Original Array: Peter, Amy
    The Shallow Copy: Peter, Amy
    

    So how does a simple equal sign, =, behave?

    It makes a reference copy. Any change to the elements or the referred objects will be reflected in both the original array and the "copied" array.

    // Create a reference copy.
    var arrPersonR = arrPerson;
    
    // Change the name of the first person.
    arrPersonR[0].Name = "NameChanged";
    // Replace the second person.
    arrPersonR[1] = new Person(){ Name = "PersonChanged" };
    
    // Display the contents of all arrays.
    Console.WriteLine( "After changing the reference copy:" );
    Console.WriteLine( $"The Original Array: {arrPerson[0].Name}, {arrPerson[1].Name}" );
    Console.WriteLine( $"The Reference Copy: {arrPersonR[0].Name}, {arrPersonR[1].Name}" );
    

    Results:

    The Original Array: NameChanged, PersonChanged
    The Reference Copy: NameChanged, PersonChanged
    

    In conclusion, ob2 = ob1 is not a shallow copy but a reference copy.

    Full code to play with:

    void Main()
    {
        // Create 2 Persons.
        var person1 = new Person(){ Name = "Jack" };
        var person2 = new Person(){ Name = "Amy" };
    
        // Create a Person array.
        var arrPerson = new Person[] { person1, person2 };
    
        // ----------- 1. A shallow copy copies elements. -----------
    
        // Create a shallow copy.
        var arrPersonClone = (Person[]) arrPerson.Clone();
    
        // Replace an element in the shallow copy.
        arrPersonClone[0] = new Person(){Name = "Peter"};
    
        // Display the contents of all arrays.
        Console.WriteLine( "After replacing the first element in the Shallow Copy:" );
        Console.WriteLine( $"The Original Array: {arrPerson[0].Name}, {arrPerson[1].Name}" );
        Console.WriteLine( $"The Shallow Copy: {arrPersonClone[0].Name}, {arrPersonClone[1].Name}" );
    
        Console.WriteLine( "\n" );
    
        // ----------- 2. A shallow copy retains the original references of the elements. -----------
    
        // Create a new shallow copy.
        arrPersonClone = (Person[]) arrPerson.Clone();
    
        // Change the name of the first person in the shallow copy.
        arrPersonClone[0].Name = "Peter";
    
        // Display the contents of all arrays.
        Console.WriteLine( "After changing the Name property of the first element in the Shallow Copy:" );
        Console.WriteLine( $"The Original Array: {arrPerson[0].Name}, {arrPerson[1].Name}" );
        Console.WriteLine( $"The Shallow Copy: {arrPersonClone[0].Name}, {arrPersonClone[1].Name}" );
    
        Console.WriteLine( "\n" );  
    
        // ----------- 2. The equal sign. -----------
    
        // Create a reference copy.
        var arrPersonR = arrPerson;
    
        // Change the name of the first person.
        arrPersonR[0].Name = "NameChanged";
        // Replace the second person.
        arrPersonR[1] = new Person(){ Name = "PersonChanged" };
    
        // Display the contents of all arrays.
        Console.WriteLine( "After changing the reference copy:" );
        Console.WriteLine( $"The Original Array: {arrPerson[0].Name}, {arrPerson[1].Name}" );
        Console.WriteLine( $"The Reference Copy: {arrPersonR[0].Name}, {arrPersonR[1].Name}" );
    }
    
    class Person
    {
        public string Name {get; set;}
    }
    

提交回复
热议问题