深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是在复制对象时涉及的两个不同概念
在C#中,实现对象的完全拷贝可以通过实现ICloneable接口或使用序列化和反序列化的方法来完成
实现ICloneable接口,需要自己实现Clone方法返回一个深拷贝对象,这边不做赘述。
下面使用通过将对象序列化到内存流,然后再反序列化为新的对象这种方式实现深拷贝。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace frameWorkTest1.utils
{
/// <summary>
/// 深拷贝扩展方法
/// </summary>
public static class DeepCopyExtensions
{
public static T DeepCopy<T>(this T source)
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException("The type must be serializable.", nameof(source));
}
// Perform deep copy using serialization
using (MemoryStream memoryStream = new MemoryStream())
{
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(memoryStream, source);
memoryStream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(memoryStream);
}
}
}
}
这边举个例子 User类的 有个类型为B的属性GetB
[Serializable]
public class User
{
private string _userName;
public string UserName
{
get { return _userName; }
set { _userName = value; }
}
private int _age;
public int Age
{
get { return _age; }
set { _age = value; }
}
private B _b;
public B GetB
{
get { return _b; }
set { _b = value; }
}
/// <summary>
/// 浅拷贝
/// </summary>
/// <returns></returns>
public User ShallowCopy()
{
// 浅拷贝,使用Object受保护方法MemberwiseClone
return (User) this.MemberwiseClone();
}
/// <summary>
/// 深拷贝
/// </summary>
/// <returns></returns>
public User DeepCopyS()
{
// 调用扩展方法进行深拷贝
return this.DeepCopy();
}
}
[Serializable]
public class B
{
private int _Num;
public int Num
{
get { return _Num; }
set { _Num = value; }
}
}
使用深拷贝
User user = new User() {
UserName = "小米",Age = 18,GetB = new B { Num = 255}
};
// 深拷贝
User user1 = user.DeepCopyS();
user1.GetB.Num = 188;
Console.WriteLine($"user:{user.GetB.Num},user1:{user1.GetB.Num}");
总体而言,深拷贝创建了原始对象及其嵌套对象的独立副本,而浅拷贝创建了原始对象及其嵌套对象的引用副本。选择使用深拷贝还是浅拷贝取决于你的需求和数据结构的复杂性。在处理嵌套引用类型时,深拷贝通常更安全,但也可能更耗费资源。
在C#中浅拷贝可以直接使用Object受保护方法MemberwiseClone
参考上述深拷贝中的代码
public User ShallowCopy()
{
// 浅拷贝,使用Object受保护方法MemberwiseClone
return (User) this.MemberwiseClone();
}
User user2 = user.ShallowCopy();
user2.GetB.Num = 100;
Console.WriteLine($"user:{user.GetB.Num},user2:{user2.GetB.Num}");