• 常用
  • 百度
  • google
  • 站内搜索

科技

C中深拷贝与浅拷贝的实现方法及ICloneable接口与序列化应用

  • 更新日期:2025-11-30
  • 查看次数:4049

浅拷贝复制值类型和引用地址,深拷贝递归复制所有引用对象。C#中可通过ICloneable接口实现浅拷贝,序列化(如System.Text.Json)实现深拷贝,或手动重写Clone方法实现深拷贝,根据性能与隔离需求选择合适方式。

C#怎么实现深拷贝和浅拷贝 C# ICloneable接口和序列化实现对象复制

在C#中,实现对象复制主要有两种方式:浅拷贝(Shallow Copy)和深拷贝(Deep Copy)。理解它们的区别并选择合适的方法对程序的正确性和性能至关重要。下面介绍如何使用 ICloneable 接口序列化 来实现这两种拷贝方式。

浅拷贝与深拷贝的区别

浅拷贝:创建一个新对象,然后将原对象的字段逐个复制到新对象中。对于值类型字段,会复制实际值;对于引用类型字段,只复制引用地址,不复制引用的对象本身。因此,原始对象和副本共享引用类型的实例。

深拷贝:不仅复制对象本身,还会递归复制所有被引用的对象,使副本与原对象完全独立,互不影响。

使用 ICloneable 接口实现浅拷贝

C# 提供了 ICloneable 接口,它包含一个 Clone 方法,可用于实现拷贝逻辑。

下面是一个实现浅拷贝的例子:

public class Person : ICloneable
{
    public string Name { get; set; }
    public Address Address { get; set; }
public object Clone()
{
    return this.MemberwiseClone(); // 浅拷贝
}

}

public class Address { public string City { get; set; } }

测试代码:

var addr = new Address { City = "Beijing" };
var person1 = new Person { Name = "Alice", Address = addr };
var person2 = (Person)person1.Clone();

person2.Address.City = "Shanghai";

Console.WriteLine(person1.Address.City); // 输出:Shanghai

可以看到,修改 person2 的 Address 会影响 person1,因为 Address 是引用类型,MemberwiseClone 只复制了引用。

通过序列化实现深拷贝

要实现真正的深拷贝,可以使用**二进制序列化**或**JSON序列化**等方式,将对象完整地“保存再读取”,从而生成完全独立的副本。

使用 BinaryFormatter(注意:.NET Core/.NET 5+ 中已弃用,推荐使用其他方式)或 System.Text.Json 实现深拷贝。

示例:使用 System.Text.Json 实现深拷贝(推荐现代项目):

using System.Text.Json;

public static T DeepClone(T source) { if (source == null) return default(T);

var json = JsonSerializer.Serialize(source);
return JsonSerializer.Deserialize<T>(json);

}

使用该方法前,确保类是可序列化的:

[Serializable]
public class Person
{
    public string Name { get; set; }
    public Address Address { get; set; }
}

[Serializable] public class Address { public string City { get; set; } }

测试深拷贝:

var addr = new Address { City = "Beijing" };
var person1 = new Person { Name = "Alice", Address = addr };
var person2 = DeepClone(person1);

person2.Address.City = "Shanghai";

Console.WriteLine(person1.Address.City); // 输出:Beijing

此时 person1 不受影响,说明实现了深拷贝。

ICloneable 实现深拷贝(手动方式)

也可以在 Clone 方法中手动创建新引用对象来实现深拷贝:

public object Clone()
{
    var clone = (Person)this.MemberwiseClone();
    clone.Address = new Address 
    { 
        City = this.Address?.City 
    };
    return clone;
}

这种方式效率高,但需要为每个引用类型字段手动处理,适用于结构简单的类。

基本上就这些。根据场景选择合适的方式:简单对象可用 ICloneable + MemberwiseClone 做浅拷贝;需要完全隔离时,推荐序列化做深拷贝,尤其是嵌套复杂对象。手动深拷贝适合性能敏感且结构稳定的场景。

本文转载于:互联网 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

imtoken下载 im钱包 imtoken imtoken 快连官网 imtoken imtoken imtoken imtoken imtoken wallet imtoken imtoken官网 imtoken钱包 imtoken下载 imtoken官网 imtoken钱包 imtoken安卓下载 imtoken下载 imtoken官方下载 imtoken官网 imtoken安卓下载 imtoken下载 imtoken下载 imtoken imtoken imtoken imtoken imtoken imtoken imtoken imtoken imtoken bitget wallet telegram下载 quickq VPN trust wallet v2rayn imtoken
imtoken imtoken下载 imtoken官网 imtoken钱包 imtoken imtoken下载 imtoken官网 imtoken imtoken钱包 imtoken imtoken下载 imtoken钱包 imtoken管网 imtoken imtoken钱包 imtoken官网 imtoken imtoken下载 imtoken钱包 imtoken下载 imtoken官网 imtoken imtoken官网 imtoken下载 imtoken钱包 imtoken官网 imtoken下载 imtoken钱包 imtoken imtoken钱包 imtoken下载 imtoken官网 imtoken钱包 imtoken下载 imtoken imtoken下载 imtoken