所谓浅拷贝就是将对象中的所有字段复制到新的副本对象中;浅拷贝对于值类型与引用类型的方式有区别,值类型字段的值被复制到副本中后,在副本中的修改不会影响源对象对应的值;然而对于引用类型的字段被复制到副本中的却是引用类型的引用,而不是引用的对象,在副本中对引用类型的字段值被修改后,源对象的值也将被修改。
深拷贝也同样是将对象中的所有字段复制到副本对象中,但是,无论对象的值类型字段或者引用类型字段,都会被重新创建并复制,对于副本的修改,不会影响到源对象的本身;
这里我们需要注意一点Student中的IDCode属性是string类型,理论上string类型是引用类型,但是由于该引用类型的特殊性,Object.MemberwiseClone方法仍旧为他创建了副本,也就是说,在浅拷贝过程中,我们应该将字符串看成值类型;
建议使用序列化的形式来进行深拷贝
#region 拷贝主体 /// <summary> /// 深度拷贝 /// </summary> /// <returns></returns> public Student DeepClone() { using (Stream objectStream = new MemoryStream()) { IFormatter formatter = new BinaryFormatter(); formatter.Serialize(objectStream, this); objectStream.Seek(0,SeekOrigin.Begin); return formatter.Deserialize(objectStream) as Student; } } public object Clone() { return this.MemberwiseClone(); } #endregion
MemberwiseClone:创建当前 Object 的浅表副本。
MemberwiseClone 方法创建一个浅表副本,方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,
则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。
对于引用类型的变量,我们有种误解,认为赋值操作就是浅拷贝一种,其实不然,两者有区别。
- 浅拷贝(shallow copy)对于引用类型对象中的值类型字段进行了逐位复制。赋值运算符只是把源对象的引用赋值给目的对象,两者引用同一个对象。
- 浅拷贝后的对象的值类型字段更改不会反映到源对象,而赋值运算后的对象的值类型字段更改会反映到源对象
在C#中,我们们有三种方法实现深拷贝