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
    评论
在Python中,拷贝指的是创建一个新的对象,包含原始对象的所有内容。但是,拷贝拷贝会根据拷贝方式的不同,影响拷贝结果。 拷贝Deep Copy)是指创建一个新的对象,包含原始对象的所有内容,甚至包括原始对象中引用的对象。也就是说,拷贝会递归地复制所有对象,包括它们的内部对象。拷贝的结果是两个完全独立的对象,修改一个对象不会影响另一个对象。 拷贝Shallow Copy)是指创建一个新的对象,包含原始对象的所有内容,但不会递归复制原始对象中引用的对象。也就是说,拷贝只复制对象的顶层内容,而不会对其内部对象进行复制。拷贝的结果是两个对象共享同一个内部对象,修改一个对象会影响另一个对象。 下面是一个例子,可以更好地说明拷贝拷贝的区别: ```python import copy # 定义一个列表 a = [1, 2, [3, 4]] # 拷贝 b = copy.copy(a) # 拷贝 c = copy.deepcopy(a) # 修改a的第二个元素 a[1] = 5 # 修改a的第三个元素中的第一个元素 a[2][0] = 6 # 输出a、b、c的值 print(a) # [1, 5, [6, 4]] print(b) # [1, 2, [6, 4]] print(c) # [1, 2, [3, 4]] ``` 在上面的例子中,我们先定义了一个列表a,它包含了一个嵌套列表。我们使用copy.copy()和copy.deepcopy()对a进行拷贝,并修改原始列表a的值。最后,我们输出了三个列表的值,可以看到,拷贝b的第三个元素的值也被修改了,而拷贝c的值没有受到影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值