DeepClone与ShadowClone
杳MSDN知:
ArrayList.Clone 方法
下面给出一个完整的例子:
ArrayList.Clone 方法
创建ArrayList 的浅表副本。
命名空间:System.Collections
程序集:mscorlib(在 mscorlib.dll 中)
集合的浅表副本仅复制集合的元素(不论它们是引用类型还是值类型),但不复制引用所引用的对象。新集合中的引用与原始集合中的引用指向相同的对象。
与之相对,集合的深层副本将复制这些元素以及由它们直接或间接引用的所有内容。
据此,说明如下 :下面给出一个完整的例子:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace CloneObjectTest
{
// Just added to show the difference between shallow and deep cloning
[Serializable()]
class SampleRefType
{
public int Val;
}
[Serializable()]
class Employee
{
public string m_Name;
public Int16 m_age;
public SampleRefType someObject;
public void Print()
{
Console.WriteLine("Name : " + m_Name);
Console.WriteLine("Age : " + m_age);
Console.WriteLine("Some Value: " + someObject.Val);
}
// This is one way to do deep cloning. But works only if the
// objects and its references are serializable
public Employee DeepClone()
{
MemoryStream m = new MemoryStream();
BinaryFormatter b = new BinaryFormatter();
b.Serialize(m, this);
m.Position = 0;
return (Employee)b.Deserialize(m);
}
// Do shallow cloning
public Employee ShallowClone()
{
return (Employee)this.MemberwiseClone();
}
static void Main(string[] args)
{
SampleRefType objRef = new SampleRefType();
objRef.Val = 1000;
Employee objA = new Employee();
objA.m_Name = "Manoj";
objA.m_age = 23;
objA.someObject = objRef;
Employee objB = objA.DeepClone();
Employee objC = objA.ShallowClone();
//objB is a deep clone. So chages made to objRef would not affect objB's value.
//But objC is shallow cloned. So, if the objRef is changed, so is the value in
//ObjC. So objC should print 2000 whereas objB should print 1000
objRef.Val = 2000;
//Updating some state
objC.m_age = 100;
objB.m_Name = "New Name";
Console.WriteLine("Original Object:");
objA.Print();
Console.WriteLine();
Console.WriteLine("Shallow Cloned Object:");
objC.Print();
Console.WriteLine();
Console.WriteLine("Deep Cloned Object:");
objB.Print();
}
}
}
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace CloneObjectTest
{
// Just added to show the difference between shallow and deep cloning
[Serializable()]
class SampleRefType
{
public int Val;
}
[Serializable()]
class Employee
{
public string m_Name;
public Int16 m_age;
public SampleRefType someObject;
public void Print()
{
Console.WriteLine("Name : " + m_Name);
Console.WriteLine("Age : " + m_age);
Console.WriteLine("Some Value: " + someObject.Val);
}
// This is one way to do deep cloning. But works only if the
// objects and its references are serializable
public Employee DeepClone()
{
MemoryStream m = new MemoryStream();
BinaryFormatter b = new BinaryFormatter();
b.Serialize(m, this);
m.Position = 0;
return (Employee)b.Deserialize(m);
}
// Do shallow cloning
public Employee ShallowClone()
{
return (Employee)this.MemberwiseClone();
}
static void Main(string[] args)
{
SampleRefType objRef = new SampleRefType();
objRef.Val = 1000;
Employee objA = new Employee();
objA.m_Name = "Manoj";
objA.m_age = 23;
objA.someObject = objRef;
Employee objB = objA.DeepClone();
Employee objC = objA.ShallowClone();
//objB is a deep clone. So chages made to objRef would not affect objB's value.
//But objC is shallow cloned. So, if the objRef is changed, so is the value in
//ObjC. So objC should print 2000 whereas objB should print 1000
objRef.Val = 2000;
//Updating some state
objC.m_age = 100;
objB.m_Name = "New Name";
Console.WriteLine("Original Object:");
objA.Print();
Console.WriteLine();
Console.WriteLine("Shallow Cloned Object:");
objC.Print();
Console.WriteLine();
Console.WriteLine("Deep Cloned Object:");
objB.Print();
}
}
}