在System.Object类中,有一个受保护的方法object.MemberwiseClone(),这个方法实现了对象的复制。事实上,它所实现的就是我们所称的浅拷贝。
深拷贝:指的是拷贝一个对象时,不仅仅把对象的引用进行复制,还把该
对象引用的值也一起拷贝。这样进行深拷贝后的拷贝对象就和源对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。
浅拷贝:指的是拷贝一个对象时,仅仅拷贝对象的引用进行拷贝,但是拷贝对象和源对象还是引用同一份实体。此时,其中一个对象的改变都会影响到另一个对象。
类型基类System.Object已经为所有类型都实现了浅拷贝,类型所要做的就是公开一个复制的接口,而通常的,这个接口会借由实现ICloneable接口来实现。ICLoneable只包含一个Clone方法。该方法既可以被实现为浅拷贝也可以被实现为深拷贝,具体如何取舍需要根据具体类型的需求来决定。
using System;
namespace DeepCopy
{
class Program
{
static void Main(string[] args)
{
// 定义原始对象
DpCopy dc = new DpCopy();
dc._i = 10;
dc._a = new A();
// 定义深拷贝对象
DpCopy deepClone = (DpCopy)dc.Clone();
// 定义浅拷贝对象
DpCopy shadowclone = (DpCopy)dc.MemberwiseClone();
// 深拷贝的复制对象将拥有自己的引用类型成员对象
// 所以这里的赋值不会影响原始对象
deepClone._a._s = "我是深拷贝的A";
Console.WriteLine(dc);
Console.WriteLine(deepClone);
Console.WriteLine("\r\n");
// 浅拷贝的复制对象共享原始对象的引用类型成员对象
// 所以这里的赋值将影响原始对象
shadowclone._a._s = "我是浅拷贝的A";
Console.WriteLine(dc);
Console.WriteLine(shadowclone);
Console.ReadKey();
}
}
public class DpCopy : ICloneable
{
public int _i = 0;
public A _a = new A();
public object Clone()
{
// 实现深拷贝
DpCopy newDc = new DpCopy();
// 重新实例化一个引用类型变量
newDc._a = new A();
// 给新引用类型变量的成员值
newDc._a._s = _a._s;
newDc._i = _i;
return newDc;
}
// 实现浅拷贝
public new object MemberwiseClone()
{
return base.MemberwiseClone();
}
/// <summary>
/// 重写类的ToString()方法
/// </summary>
/// <returns></returns>
public override string ToString()
{
return "I的值为:" + _i.ToString() + ",A为:" + _a._s;
}
}
/// <summary>
/// 包含一个引用成员的类型
/// </summary>
public class A
{
public string _s = "我是原始A";
}
}