C # class shallow copy and deep copy

MemberwiseClone method creates a shallow copy, specifically, is to create a new object, and then copy the non-static fields of the current object to the new object. 
If the field is a value type, then the field is performed bit by bit copy. If the field is a reference type, then copy references but does not copy the objects referenced; therefore, a copy of the original object and reference the same object.

In order to achieve a deep copy, we must have each traverse FIG objects referenced configuration, and processing cycles which require a reference structure. This is undoubtedly very complex. Fortunately, by means of serialization and de-serialization mechanism .Net can be very simple depth Clone an object. The principle is simple, the first object serialization stream into memory, which is the object and object-object references the state are saved to memory. .Net serialization mechanism automatically handling of circular references. Memory status information is then deserialize the stream to a new object. Such a deep copy of the object is complete. In the prototype design mode CLONE technology is critical.

The following code demonstrates the problem:

Copy the code
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace CloneDemo
{
[Serializable]
class DemoClass
{
    public int i = 0;
    public int[] iArr = { 1, 2, 3 };
 
    public DemoClass Clone1() //浅CLONE
    {
        return this.MemberwiseClone() as DemoClass;
    }
 
    public DemoClass Clone2() //深clone
    {
        MemoryStream stream = new MemoryStream();
        BinaryFormatter formatter = new BinaryFormatter();
        formatter.Serialize(stream, this);
        stream.Position = 0;
        return formatter.Deserialize(stream) as DemoClass;
    } 
} 
 
class Program
{ 
    Static void the Main (String [] args) 
    { 
        DemoClass new new DemoClass A = (); 
        AI = 10; 
        a.iArr = new new int [] {. 8,. 9, 10}; 
        DemoClass a.Clone1 B = (); 
        c = a.Clone2 DemoClass (); 
 
        // change a target iArr [0], resulting in the object iArr b [0] and c has changed without changes 
          a.iArr [0] = 88; 
 
        Console.WriteLine ( "MemberwiseClone"); 
        Console.WriteLine (BI); 
        the foreach (Item in b.iArr var) 
        { 
            Console.WriteLine (Item); 
        } 
 
        Console.WriteLine ( "clone2"); 
        Console.WriteLine (CI); 
        the foreach (var Item in c.iArr) 
        { 
            Console.WriteLine (Item );
        }
 
        Console.ReadLine();
    }
}
}
Copy the code

Another example is for an array, C # in the array is a reference type variable, we demonstrate through the array: 
shallow copy

Copy the code
using System;

class ShallowCopy : ICloneable
{
public int[] v = {1,2,3};

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

public void Display()
{
foreach(int i in v)
Console.Write( i + ", ");
Console.WriteLine();
}
}

class Client
{
public static void Main()
{

ShallowCopy sc1 = new ShallowCopy();
ShallowCopy sc2 = (ShallowCopy)sc1.Clone();
sc1.v[0] = 9;
 
sc1.Display();
sc2.Display();

}
}
Copy the code

ShallowCopy object implements a shallow copy, and therefore When sc1 cloning, its fields v and no clone, which results in field v sc1 and sc2 are pointing to the same v, and therefore, when the modified v sc1 [0] , sc2 to v [0] has changed.

Deep copy:

Copy the code
the System the using; 

class a DeepCopy: the ICloneable 
{ 
public int [] V = {l, 2,3}; 

// default constructor 
public a DeepCopy () 
{ 
} 

private constructor method call // Clone for 
private DeepCopy (int [] v ) 
{ 
this.v = (int []) v.Clone (); 
} 

public Object Clone () 
{ 
// DeepCopy construct a new object parameter is configured 
v // used in the original object 
return new DeepCopy (this .v); 
} 

public void Display () 
{ 
the foreach (int I in V) 
Console.Write (I + ","); 
Console.WriteLine (); 

} 
} 

class Client 
{ 
public static void the Main () 
{  
a DeepCopy DC1 = new DeepCopy ();
a DeepCopy DC2 = (DeepCopy) dc1.Clone ();
dc1.v[0] = 9;
 
dc1.Display();
dc2.Display();

}
}
Copy the code

The cloning of the time, not only clone themselves, even inside the array of field together cloning. Therefore, the final print out dc1 and dc2 different.

Of course, we can also help build a deep copy of class:

Copy the code
public static class ObjectCopier
{
    
/// <summary>
/// Perform a deep Copy of the object.
/// </summary>
/// <typeparam name="T">The type of object being copied.</typeparam>
/// <param name="source">The object instance to copy.</param>
/// <returns>The copied object.</returns>
public static T Clone<T>(T source)
{
    if (!typeof(T).IsSerializable)
    {
        throw new ArgumentException("The type must be serializable.", "source");
    }
 
    // Don't serialize a null object, simply return the default for that object
    if (Object.ReferenceEquals(source, null))
    {
        return default(T);
    }
 
    IFormatter formatter = new BinaryFormatter();
    Stream stream = new MemoryStream();
    using (stream)
    {
        formatter.Serialize(stream, source);
        stream.Seek(0, SeekOrigin.Begin);
        return (T)formatter.Deserialize(stream);
    }
}

}
Copy the code
Transfer: https: //www.cnblogs.com/MRRAOBX/articles/4084171.html

Guess you like

Origin www.cnblogs.com/wangyu19900123/p/11126711.html