Tip14 正确实现浅拷贝和深拷贝
浅拷贝:将对象中的所有字段复制到新的对象(副本)中。复制以后,若在副本中修改值类型的字段的值,不会影响到源对象对应的值,但修改引用类型的字段的值,会影响到源对象本身。
深拷贝:将对象中的所有字段复制到新的对象(副本)中。但是复制以后,对于副本的修改都不会影响到源对象本身。
拷贝建议用类型继承ICloneable接口。例如:
[Serializable]
class Department
{
public string Name { get; set; }
public override string ToString()
{
return this.Name;
}
}
[Serializable]
class Employee : ICloneable
{
public string IDCode { get; set; }
public int Age { get; set; }
public Department Department { get; set; }
public object Clone()
{
//浅拷贝
return this.MemberwiseClone();
}
/// <summary>
/// 浅拷贝
/// </summary>
/// <returns></returns>
public Employee ShalllowClone()
{
return Clone() as Employee;
}
/// <summary>
/// 深拷贝
/// </summary>
/// <returns></returns>
public Employee DeepClone()
{
//使用序列化来进行深拷贝
using (Stream objectStream = new MemoryStream())
{
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(objectStream, this);
objectStream.Seek(0, SeekOrigin.Begin);
return formatter.Deserialize(objectStream) as Employee;
}
}
}
调用如下:
Employee mike = new Employee() { IDCode = "NB123", Age = 30, Department = new Department() { Name = "Dep1" } };
Employee rose = mike.ShalllowClone() as Employee;
//Employee rose = mike.DeepClone() as Employee;
Console.WriteLine(rose.IDCode);
Console.WriteLine(rose.Age);
Console.WriteLine(rose.Department);
Console.WriteLine("开始改变Mike的值:");
mike.IDCode = "NB456";
mike.Age = 60;
mike.Department.Name = "Dep2";
Console.WriteLine(rose.IDCode);
Console.WriteLine(rose.Age);
Console.WriteLine(rose.Department);
//浅拷贝时输出如下:
NB123
30
Dep1
开始改变Mike的值:
NB123
30
Dep2
//深拷贝时输出如下:
NB123
30
Dep1
开始改变Mike的值:
NB123
30
Dep1
可以看到浅拷贝时,改变了源对象mike中的Department的值,副本rose的Department的值也随之变动。而深拷贝则完全不影响。