浅拷贝和深拷贝之间的区别:浅拷贝是指将对象中的数值类型的字段拷贝到新的对象中,而对象中的引用型字段则指复制它的一个引用到目标对象。如果改变目标对象中引用型字段的值他将反映在原是对象中,也就是说原始对象中对应的字段也会发生变化。深拷贝与浅拷贝不同的是对于引用的处理,深拷贝将会在新对象中创建一个新的和原是对象中对应字段相同(内容相同)的字段,也就是说这个引用和原是对象的引用是不同的,我们在改变新对象中的这个字段的时候是不会影响到原始对象中对应字段的内容。
如何实现深拷贝?
实现IClonable接口,Override父类的Clone()函数
Public Function Clone() As Object Implements IClonable
一般的方法:New一个要clone的新对象,将原对象中成员的值赋给新对象的成员,返回该新对象的引用。
较好的办法:将对象序列化到一个System.IO.MemoryStream中,然后立即对该内存流执行反序列化,从而得到一个新的对象。但好像不是任何对象都可以序列化!
下面是上次写的一个用序列化方法实现的Prototype的深拷贝代码,可供大家参考——注意其中Clone方法不是虚方法,写一次就可以满足所有子类的需要:
using
System;
using System.Runtime;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
// 抽象原型
[Serializable]
public abstract class Prototype
{
public abstract int I
{
get ;
set ;
}
public abstract string S
{
get ;
set ;
}
public abstract int [] A
{
get ;
set ;
}
public abstract void print();
public Prototype Clone()
{
MemoryStream stream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, this );
stream.Position = 0 ;
return (Prototype)formatter.Deserialize(stream);
}
}
[Serializable]
public class ConcretePrototype : Prototype
{
public int i;
public string s;
public int [] a;
public override int I
{
get { return i; }
set { this .i = value; }
}
public override string S
{
get { return s; }
set { this .s = value; }
}
public override int [] A
{
get { return a; }
set { this .a = value; }
}
public override void print()
{
Console.Write( " i={0}, s={1}, a={2} " , i, s, a);
foreach ( int item in a) { Console.Write(item + " , " ); }
Console.WriteLine();
}
}
public class GameSystem
{
public void Run(Prototype prototype)
{
Prototype item1 = prototype.Clone();
item1.I = 100 ;
item1.S = " hello " ;
item1.A = new int [] { 1 , 2 , 3 };
Prototype item2 = prototype.Clone();
item2.I = 400 ;
item2.S = " world " ;
item2.A = new int [] { 100 , 200 , 300 };
item1.print();
item2.print();
Console.WriteLine(item1);
}
}
class App
{
public static void Main()
{
GameSystem gameSystem = new GameSystem();
gameSystem.Run( new ConcretePrototype());
}
}
using System.Runtime;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
// 抽象原型
[Serializable]
public abstract class Prototype
{
public abstract int I
{
get ;
set ;
}
public abstract string S
{
get ;
set ;
}
public abstract int [] A
{
get ;
set ;
}
public abstract void print();
public Prototype Clone()
{
MemoryStream stream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, this );
stream.Position = 0 ;
return (Prototype)formatter.Deserialize(stream);
}
}
[Serializable]
public class ConcretePrototype : Prototype
{
public int i;
public string s;
public int [] a;
public override int I
{
get { return i; }
set { this .i = value; }
}
public override string S
{
get { return s; }
set { this .s = value; }
}
public override int [] A
{
get { return a; }
set { this .a = value; }
}
public override void print()
{
Console.Write( " i={0}, s={1}, a={2} " , i, s, a);
foreach ( int item in a) { Console.Write(item + " , " ); }
Console.WriteLine();
}
}
public class GameSystem
{
public void Run(Prototype prototype)
{
Prototype item1 = prototype.Clone();
item1.I = 100 ;
item1.S = " hello " ;
item1.A = new int [] { 1 , 2 , 3 };
Prototype item2 = prototype.Clone();
item2.I = 400 ;
item2.S = " world " ;
item2.A = new int [] { 100 , 200 , 300 };
item1.print();
item2.print();
Console.WriteLine(item1);
}
}
class App
{
public static void Main()
{
GameSystem gameSystem = new GameSystem();
gameSystem.Run( new ConcretePrototype());
}
}