c# 浅拷贝(Shallow Copy)和深拷贝(Deep Copy)

在C#中,拷贝对象有两种方式:浅拷贝(Shallow Copy)和深拷贝(Deep Copy)。理解这两种拷贝的区别对于管理对象和避免在程序中意外地共享或复制数据至关重要。

浅拷贝(Shallow Copy)

浅拷贝创建一个新的对象,然后将原始对象的非静态字段复制到该对象。如果字段是值类型的,则进行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其副本引用同一个对象。

在C#中,可以通过几种方式实现浅拷贝,如使用Object.MemberwiseClone()方法,这是System.Object类提供的受保护方法,能够创建当前对象的浅表副本。

浅拷贝示例:
public class Person
{
    public int Age;
    public string Name;
    public Company Work; // 引用类型

    public Person ShallowCopy()
    {
        return (Person)this.MemberwiseClone();
    }
}

public class Company
{
    public string Name;
    public Company(string name)
    {
        this.Name = name;
    }
}

// 使用浅拷贝
var original = new Person { Age = 30, Name = "John", Work = new Company("XYZ Inc") };
var copy = original.ShallowCopy();

// 修改副本
copy.Work.Name = "ABC Corp";
// 现在original.Work.Name也会显示"ABC Corp",因为Work对象在original和copy之间共享。

深拷贝(Deep Copy)

深拷贝创建一个新对象,然后将原始对象的所有字段复制到新对象。如果字段是值类型,则执行逐位复制。如果字段是引用类型,则复制引用所指向的对象及其所有子对象,这样,副本和原始对象不会共享任何子对象。

实现深拷贝的一种方法是通过序列化对象到内存流,然后再反序列化。这种方法适用于所有字段支持序列化的对象。

深拷贝示例:
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

public static T DeepCopy<T>(T obj)
{
    using (var memoryStream = new MemoryStream())
    {
        var formatter = new BinaryFormatter();
        formatter.Serialize(memoryStream, obj);
        memoryStream.Seek(0, SeekOrigin.Begin);
        return (T)formatter.Deserialize(memoryStream);
    }
}

// 应确保Person类和Company类都标记为[Serializable]以允许序列化。
[Serializable]
public class Person
{
    public int Age;
    public string Name;
    public Company Work;
}

[Serializable]
public class Company
{
    public string Name;
    public Company(string name)
    {
        Name = name;
    }
}

// 使用深拷贝
var original = new Person { Age = 30, Name = "John", Work = new Company("XYZ Inc") };
var copy = DeepCopy(original);

// 修改副本
copy.Work.Name = "ABC Corp";
// original.Work.Name 不变,仍为"XYZ Inc"

//使用System.Text.Json序列化方法

public T deepcopy<T>(T t)
{ 
	 string str= System.Text.Json.JsonSerializer.Serialize(t);
	 //会创建一个新的对象
	 return System.Text.Json.JsonSerializer.Deserialize<T>(str);	
}

序列化与安全性

使用序列化来执行深拷贝非常方便,但要注意,使用BinaryFormatter可能带来安全风险(如潜在的代码执行攻击)。因此,建议在需要深拷贝且关心安全性时,查找或实现其他不使用BinaryFormatter的深拷贝方法,例如使用Newtonsoft.Json.NETSystem.Text.Json进行序列化和反序列化。

  • 14
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值