.NET中深复制(deep copy)与浅复制(shallow copy)

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

浅复制:

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

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

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

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

下面是一个示例:

View Code
   
     
class ShallowCopy
{
public static string CompanyName = " My Company " ;
public int Age;
public string EmployeeName;
public CLSRefSalary clsRefSalary ;

public ShallowCopy CreateShallowCopy(ShallowCopy inputShallowCopy)
{
return (ShallowCopy)inputShallowCopy.MemberwiseClone();
}
}
class CLSRefSalary
{
public CLSRefSalary( int _salary)
{
Salary
= _salary;
}
public int Salary;
}

View Code
   
     
class Program
{
static void 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
{
public static string CompanyName = " My Company " ;
public int Age;
public string 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;
}
public int Salary;
}
View Code
    
      
class Program
{
static void 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()方法
   
     
public static 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;
}

你可能感兴趣的:(.net)