深复制(deep copy)和浅复制(shallow copy)

转自:http://www.cnblogs.com/jackal/archive/2011/04/29/2032613.html

 

深复制(deep copy)和浅复制(shallow copy)都是用于对象之间的拷贝。  注:参考CodeProject  

浅复制:

创建一个新对象, 然后将当前对象的非静态字段拷贝到新对象.

如果字段是值类型的, 在堆栈上开辟一个新的空间, 将该字段进行逐位复制到新空间.

如果字段是引用类型的, 在堆栈区域开辟一个存放引用的空间, 将当前对象的引用复制到此空间, 而引用的对象不变.  因此, 原始对象及其复本引用同一对象。

在C#中创建一个浅表副本, 也就是克隆一个新的对象 使用MemberwiseClone()方法,返回一个当前对象的浅表副本。

下面是一个示例:

 

View Code
复制代码
class ShallowCopy
{
publicstaticstring CompanyName ="My Company";
publicint Age;
publicstring EmployeeName;
public CLSRefSalary clsRefSalary ;

public ShallowCopy CreateShallowCopy(ShallowCopy inputShallowCopy)
{
return (ShallowCopy)inputShallowCopy.MemberwiseClone();
}
}
class CLSRefSalary
{
public CLSRefSalary(int _salary)
{
Salary
= _salary;
}
publicint Salary;
}
复制代码

 

View Code
复制代码
class Program
{
staticvoid Main(string[] args)
{
//创建一个ShallowCopy的实例shallowCopy
ShallowCopy shallowCopy =new ShallowCopy();
shallowCopy.Age
=25;
shallowCopy.EmployeeName
="Ahmed Eid";

//创建一个CLSRefSalary实例,并赋值给shallowCopy对象的clsRefSalary
CLSRefSalary clsRefSalary =new CLSRefSalary(1000);
shallowCopy.clsRefSalary
= clsRefSalary;

//创建一个ShallowCopy的浅副本shallowCopy2
ShallowCopy shallowCopy2 = shallowCopy.CreateShallowCopy(shallowCopy);

//改变shallowCopy2中引用对象clsRefSalary里字段Salary的值
shallowCopy2.clsRefSalary.Salary =2000;

//检查原对象shallowCopy中引用对象clsRefSalary的值,结果EmpSalary=2000
//所以浅复制只是拷贝了引用类型在堆栈区域的引用, 而没有拷贝引用类型在托管堆上的对象,原引用和拷贝后的引用都是指向托管堆的同一个位置
int EmpSalary = shallowCopy.clsRefSalary.Salary;
}
}
复制代码

深复制

对于值类型深复制与浅复制相同.

对于引用类型,分别在堆栈和托管堆上开辟新的空间,将原引用对象的引用和引用的对象复制到堆栈和托管堆上.

如果要克隆一个类,则这个类必须要标记为可序列化的([Serializable])

示例:

这个实例没有去实现ICloneable接口, 也没实现里面的Clone()方法,而是自定义一个Clone()方法;

View Code
复制代码
[Serializable]
class DeepCopy
{
publicstaticstring CompanyName ="My Company";
publicint Age;
publicstring EmployeeName;
public CLSRefSalary clsRefSalary;

public DeepCopy CreateDeepCopy(DeepCopy inputDeepCopy)
{
MemoryStream m
=new MemoryStream();
BinaryFormatter b
=new BinaryFormatter();
b.Serialize(m, inputDeepCopy);
m.Position
=0;
return (DeepCopy)b.Deserialize(m);
}
}

[Serializable]
class CLSRefSalary
{
public CLSRefSalary(int _salary)
{
Salary
= _salary;
}
publicint Salary;
}
复制代码
 
 
View Code
复制代码
class Program
{
staticvoid Main(string[] args)
{
//创建一个DeepCopy实例
DeepCopy deepCopy =new DeepCopy();
deepCopy.Age
=25;
deepCopy.EmployeeName
="Ahmed Eid";

//创建CLSRefSalary实例,赋值给deepCopy对象的clsRefSalary
CLSRefSalary clsRefSalary =new CLSRefSalary(1000);
deepCopy.clsRefSalary
= clsRefSalary;

//创建一个DeepCopy的浅副本deepCopy2
DeepCopy deepCopy2 = deepCopy.CreateDeepCopy(deepCopy);

//改变deepCopy2中引用对象clsRefSalary里字段Salary的值
deepCopy2.clsRefSalary.Salary =2000;

//检查原对象deepCopy中引用对象clsRefSalary的值,结果EmpSalary=1000
int EmpSalary = deepCopy.clsRefSalary.Salary;
}
}
复制代码
对于CreateDeepCopy()可以用泛型实现一个通用的Clone()方法
复制代码
publicstatic T CreateDeepCopy<T>(T item)
{
BinaryFormatter formatter
=new BinaryFormatter();
MemoryStream stream
=new MemoryStream();
formatter.Serialize(stream, item);
stream.Seek(
0, SeekOrigin.Begin);
T result
= (T)formatter.Deserialize(stream);
stream.Close();
return result;
}
复制代码
原文地址:https://www.cnblogs.com/Jenny90/p/3018538.html