C#开发常见面试题三(浅复制和深复制的区别)
一.浅复制和深复制定义
(1)浅复制:复制一个对象的时候,仅仅复制原始对象中所有的非静态类型成员和所有的引用类型成员的引用。(新对象和原对象将共享所有引用类型成员的实际对象)
(2)深复制:复制一个对象的时候,不仅复制所有非静态类型成员,还要复制所有引用类型成员的实际对象。
在.NET中,基类System.Object已经为所有类型都实现了浅复制,类型所要做的就是公开一个复制的接口,而通常的,这个接口会由ICloneable接口来实现。ICloneable只包含一个方法Clone,该方法既可以被实现为浅复制也可以被实现为深复制,具体如何取舍则根据具体类型的需求决定。此外,在Sys-tem.Object基类中,有一个保护的MemeberwiseClone()方法,它便用于进行浅度复制。
二.代码理解
public object Clone()
{
return MemberwiseClone();
}
实例
public class DeepCopy : ICloneable
{
public int i = 0;
public A a = new A();
public object Clone()
{
// 实现深复制-方式1:依次赋值和实例化
DeepCopy newObj = new DeepCopy();
newObj.a = new A();
newObj.a.message = this.a.message;
newObj.i = this.i;
return newObj;
}
public new object MemberwiseClone()
{
// 实现浅复制
return base.MemberwiseClone();
}
public override string ToString()
{
string result = string.Format("I的值为{0},A为{1}", this.i.ToString(), this.a.message);
return result;
}
}
public class A
{
public string message = "我是原始A";
}
public class Program
{
static void Main(string[] args)
{
DeepCopy dc = new DeepCopy();
dc.i = 10;
dc.a = new A();
DeepCopy deepClone = dc.Clone() as DeepCopy;
DeepCopy shadowClone = dc.MemberwiseClone() as DeepCopy;
// 深复制的目标对象将拥有自己的引用类型成员对象
deepClone.a.message = "我是深复制的A";
Console.WriteLine(dc);
Console.WriteLine(deepClone);
Console.WriteLine();
// 浅复制的目标对象将和原始对象共享引用类型成员对象
shadowClone.a.message = "我是浅复制的A";
Console.WriteLine(dc);
Console.WriteLine(shadowClone);
Console.ReadKey();
}
}
执行结果
三.如何实现深复制
1.逐个复制
2.序列化实现深复制
[Serializable]
public class DeepCopy : ICloneable
{
......
public object Clone()
{
// 实现深复制-方式1:依次赋值和实例化
//DeepCopy newObj = new DeepCopy();
//newObj.a = new A();
//newObj.a.message = this.a.message;
//newObj.i = this.i;
//return newObj;
// 实现深复制-方式2:序列化/反序列化
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, this);
ms.Position = 0;
return bf.Deserialize(ms);
}
......
}
[Serializable]
public class A
{
public string message = "我是原始A";
}
PS:一般可被继承的类型应该避免实现ICloneable接口,因为这样做将强制所有的子类型都需要实现ICloneable接口,否则将使类型的深复制不能覆盖子类的新成员。
复习一下基础知识。