在 .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>(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); } } }
2. 使用 json 序列化(newtonsoft.json 或 system.text.json)
// 使用 newtonsoft.json using newtonsoft.json; public static t deepcopy<t>(t obj) { var json = jsonconvert.serializeobject(obj); return jsonconvert.deserializeobject<t>(json); } // 使用 system.text.json (推荐.net core 3.0+) using system.text.json; public static t deepcopy<t>(t obj) { var json = jsonserializer.serialize(obj); return jsonserializer.deserialize<t>(json); }
3. 实现 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(); // 浅拷贝(因为只有值类型) } }
4. 使用 automapper(适用于复杂对象)
using automapper; var config = new mapperconfiguration(cfg => { cfg.createmap<myclass, myclass>(); cfg.createmap<myotherclass, myotherclass>(); }); var mapper = config.createmapper(); var copy = mapper.map<myclass>(original);
5. 注意事项
- 序列化方法要求所有相关类都是可序列化的(有
[serializable]
特性或可以被 json 序列化) - 循环引用可能导致堆栈溢出或序列化异常
- 性能考虑:对于大型对象图,序列化方法可能较慢
- 某些特殊类型(如委托、com 对象)可能无法正确拷贝
6. 推荐方法
- 对于简单对象:使用 json 序列化(system.text.json 性能较好)
- 对于复杂对象图:考虑实现 icloneable 或使用 automapper
- 对于性能敏感场景:考虑手动实现深拷贝逻辑
选择哪种方法取决于具体需求、对象复杂度和性能要求。
到此这篇关于.net 中的深拷贝实现方法的文章就介绍到这了,更多相关.net深拷贝内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论