在 .NET 中实现深拷贝(Deep Copy)的常用方法 首先明确概念:深拷贝并非简单复制引用指针。它意味着创建一个全新的对象,并递归地复制原对象及其内部所有引用对象的值。这与仅复制“表面”的浅拷贝有根本区别。 1. 使用序列化与反序列化 这是一种经典方法。通过将对象序列化成数据流(如二进制流),
首先明确概念:深拷贝并非简单复制引用指针。它意味着创建一个全新的对象,并递归地复制原对象及其内部所有引用对象的值。这与仅复制“表面”的浅拷贝有根本区别。
这是一种经典方法。通过将对象序列化成数据流(如二进制流),再反序列化回来,即可获得一个全新的独立副本。使用此方法的前提是所有相关类型都必须是可序列化的。
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
public static class ObjectCopier
{
public static T DeepCopy(T obj)
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException("The type must be serializable.", nameof(obj));
}
if (ReferenceEquals(obj, null))
{
return default;
}
IFormatter formatter = new BinaryFormatter();
using (var stream = new MemoryStream())
{
formatter.Serialize(stream, obj);
stream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(stream);
}
}
}
随着 JSON 的广泛应用,这种方法也日益流行。其原理是将对象转换为 JSON 字符串,再将其解析回新的对象,从而实现拷贝。可以使用 Newtonsoft.Json 或 System.Text.Json 等主流库,具体选择取决于项目环境。
// 使用 Newtonsoft.Json using Newtonsoft.Json; public static T DeepCopy(T obj) { var json = JsonConvert.SerializeObject(obj); return JsonConvert.DeserializeObject (json); } // 使用 System.Text.Json (推荐用于 .NET Core 3.0 及以上版本) using System.Text.Json; public static T DeepCopy (T obj) { var json = JsonSerializer.Serialize(obj); return JsonSerializer.Deserialize (json); }
当需要更精细的控制,或对象结构较为特殊时,手动实现 ICloneable 接口是一个可靠的选择。这种方式需要开发者亲自处理每个引用类型成员的克隆过程,因此提供了最高的灵活性。
public class MyClass : ICloneable
{
public int Value { get; set; }
public MyOtherClass Other { get; set; }
public object Clone()
{
var copy = (MyClass)MemberwiseClone(); // 先进行浅拷贝
copy.Other = (MyOtherClass)Other.Clone(); // 再手动深拷贝引用成员
return copy;
}
}
public class MyOtherClass : ICloneable
{
public string Name { get; set; }
public object Clone()
{
return MemberwiseClone(); // 如果成员均为值类型,浅拷贝即可
}
}
对于属性众多、层次复杂的对象图,配置 AutoMapper 后可以便捷地实现深拷贝。这种方法特别适合在项目已引入该库,或对象结构相对规整的场景中使用。
using AutoMapper;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap();
cfg.CreateMap();
});
var mapper = config.CreateMapper();
var copy = mapper.Map(original);
每种方法都有其适用场景和潜在问题,选择时需注意以下几点:
[Serializable] 特性或能被 JSON 序列化器处理)。面对多种选择,可依据以下思路进行决策:
System.Text.Json,在 .NET Core 环境下性能更佳)。AutoMapper,或手动实现 ICloneable 接口,以获得更好的可控性。总之,没有一种方法是绝对最优的。最佳选择应基于对具体需求、对象结构复杂度和性能要求的综合考量。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述