Shallow copy or Deep copy?

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 had gone through a lots of theory regarding this, but I need explanation with proper examples.. I have program in which I copy one object into another. -->

   class A
    {
        public int a = 0;
        public void display()
        {
            Console.WriteLine("The value of a is " + a);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            A ob1 = new A();
            ob1.a = 10;
            ob1.display();
            A ob2 = new A();
            ob2 = ob1;
            ob2.display();
            Console.Read();
        }
    }

Is this a shallow copy or a deep copy ? Can anyone please provide the answer with reason. If it is a deep copy, then please provide the code for shallow copy for this program doing the same job of object copying, and the other way around..

If the above is a shallow copy, then even this should be a shallow copy-->

            A ob1 = new A();
            ob1.a = 10;
            ob1.display();
            A ob2 = ob1;
            ob2.a = 444;
            ob1.display();

From the link here

Shallow copies duplicate as little as possible. A shallow copy of a collection is a copy of the collection structure, not the elements. With a shallow copy, two collections now share the individual elements.

Deep copies duplicate everything. A deep copy of a collection is two collections with all of the elements in the original collection duplicated.

Your example is creating a shallow copy.

A ob1 = new A();
ob1.a = 10;
A ob2 = new A();
ob2 = ob1;

ob1.a = 5; // <-- If you see value of ob2.a after this line, it will be 5.

Deep copy will be -

 A ob1 = new A();
 ob1.a = 10;
 A ob2 = new A();
 ob2.a = ob1.a;

 ob1.a = 5; // <-- If you see value of ob2.a after this line, it will be 10.

In my opinion, it is not a strict shallow copy or deep copy. If I have to define it, I would say shallow copy.

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.

Example from MSDN would be better to explain the differences for shallow copy, deep copy and just simply class copy.

 using System;

    public class IdInfo
    {
        public int IdNumber;

        public IdInfo(int IdNumber)
        {
            this.IdNumber = IdNumber;
        }
    }

    public class Person
    {
        public int Age;
        public string Name;
        public IdInfo IdInfo;

        public Person ShallowCopy()
        {
            return (Person)this.MemberwiseClone();
        }

        public Person DeepCopy()
        {
            Person other = (Person)this.MemberwiseClone();
            other.IdInfo = new IdInfo(this.IdInfo.IdNumber);
            other.Name = String.Copy(this.Name);
            return other;
        }
    }

    public class Example
    {
        public static void Main()
        {
            // Create an instance of Person and assign values to its fields.
            Person p1 = new Person();
            p1.Age = 42;
            p1.Name = "Sam";
            p1.IdInfo = new IdInfo(6565);

            // Perform a shallow copy of p1 and assign it to p2.
            Person p2 = (Person)p1.ShallowCopy();

            // Display values of p1, p2
            Console.WriteLine("Original values of p1 and p2:");
            Console.WriteLine("   p1 instance values: ");
            DisplayValues(p1);
            Console.WriteLine("   p2 instance values:");
            DisplayValues(p2);

            // Change the value of p1 properties and display the values of p1 and p2.
            p1.Age = 32;
            p1.Name = "Frank";
            p1.IdInfo.IdNumber = 7878;
            Console.WriteLine("nValues of p1 and p2 after changes to p1:");
            Console.WriteLine("   p1 instance values: ");
            DisplayValues(p1);
            Console.WriteLine("   p2 instance values:");
            DisplayValues(p2);

            // Make a deep copy of p1 and assign it to p3.
            Person p3 = p1.DeepCopy();
            // Change the members of the p1 class to new values to show the deep copy.
            p1.Name = "George";
            p1.Age = 39;
            p1.IdInfo.IdNumber = 8641;
            Console.WriteLine("nValues of p1 and p3 after changes to p1:");
            Console.WriteLine("   p1 instance values: ");
            DisplayValues(p1);
            Console.WriteLine("   p3 instance values:");
            DisplayValues(p3);

            // Make an equal of p1 and assign it to p4.
            Person p4 = new Person();
            p4 = p1;
            // Change the members of the p1 class to new values to show the equal copy.
            p1.Name = "Will";
            p1.Age = 30;
            p1.IdInfo.IdNumber = 8484;
            Console.WriteLine("nValues of p1 and p4 after changes to p1:");
            Console.WriteLine("   p1 instance values: ");
            DisplayValues(p1);
            Console.WriteLine("   p4 instance values:");
            DisplayValues(p4);
        }

        public static void DisplayValues(Person p)
        {
            Console.WriteLine("      Name: {0:s}, Age: {1:d}", p.Name, p.Age);
            Console.WriteLine("      Value: {0:d}", p.IdInfo.IdNumber);
        }
    }

Here are the results:

Original values of p1 and p2:    p1 instance values:
      Name: Sam, Age: 42
      Value: 6565    p2 instance values:
      Name: Sam, Age: 42
      Value: 6565

Values of p1 and p2 after changes to p1:    p1 instance values:
      Name: Frank, Age: 32
      Value: 7878    p2 instance values:
      Name: Sam, Age: 42
      Value: 7878

Values of p1 and p3 after changes to p1:    p1 instance values:
      Name: George, Age: 39
      Value: 8641    p3 instance values:
      Name: Frank, Age: 32
      Value: 7878

Values of p1 and p4 after changes to p1:    p1 instance values:
      Name: Will, Age: 30
      Value: 8484    p4 instance values:
      Name: Will, Age: 30
      Value: 8484

This is neither a shallow nor a deep copy, this is a reference copy.let me explain: there are 2 types of variables : value types and reference types.

a value type is a (named) location in computer memory that hold the actual value of the variable. for example: int is a value type, so when you write this line of code:

int MyInt = 5;

when this line of code get executed the runtime will find a location in the RAM and write the value 5 in it. so if you search that location you will find an actual value of 5.

a reference type -in contrast- is a (named) location in memory that does not actually hold the value of the variable but hold the location of memory where that value exists. as an example suppose you wrote the following code:

MyClass myObject = new MyClass();

what happens is that the virtual machine (runtime): 1- look and find an available location in memory , create an instance of the MyClass class. lets say that the location of that object happened to be at byte # AA3D2 in RAM.

2- find a location in memory and create a reference of type MyClass (a reference is an "arrow" that point to a location in memory),name it "myObject" and store the value AA3D2 in it.

now if you look at the "myObject" variable you will find not the class instance but you will find AA3D2 which represent the location of memory that hold that class instance.

now lets examine the code given my the OP:

A ob1 = new A();

this will make a variable called ob1 ,create instance of the A class and store the location of that class in ob1

ob1.a = 10;
ob1.display();

this will change the variable a which is inside the A class. it then invoke the display() method

A ob2 = new A();

here it create a variable called ob2 ,create an instance of the class A and assign its location to ob2.

by now you have in memory 2 class instances of A and 2 variables each pointing to one of them. now here is the interesting part : ob2 = ob1;

the variable ob2 is assigned the value of the variable ob1. because ob1 contain the memory location of the first instance of A ,now both ob1 and ob2 point to the same location in memory. doing anything using one of them is exactly doing the same thin with the other.

ob2 = ob1 means you are copying the reference.

链接地址: http://www.djcxy.com/p/13934.html

上一篇: 并行和并行逻辑编程

下一篇: 浅拷贝或深拷贝?