在不使用序列化的情况下深度复制.NET类实例

8

我正在使用第三方DLL中的实例类,并且需要对特定实例进行深度复制。该类未标记为Serializable,因此我无法使用此建议方法使用BinaryFormatter

如何在不使用序列化的情况下获得对象的深层副本?


典型的例子是单例模式类。你不应该(也不应该能够)复制它。 - Mehrdad Afshari
@Mehrdad 我现在明白你的意思了。我相信在这种情况下缺少 Serializable 是 API 开发人员缺乏远见所致。 - Josh Stodola
此外,对于诸如数据库连接、网络连接或事务等内容进行深度复制可能会导致严重的损失。 - Dour High Arch
你可以使用一个映射器,我建议使用UltraMapper https://github.com/maurosampietro/UltraMapper。 - Mauro Sampietro
请查看此答案:https://dev59.com/QF_Va4cB1Zd3GeqPTnug#52097307,了解有关无需序列化克隆对象的信息。 - Ahmed Sabry
显示剩余2条评论
3个回答

5

我一直很成功地使用Copyable。它在底层使用了反射技术,是开源的。请务必阅读限制和陷阱以确定您是否可以使用它。


我相信这对我有用,谢谢!我了解其中的陷阱,幸运的是,我目前正在处理的内容绝对没有未受控制的资源。再次感谢,我会告诉你它的效果如何。 - Josh Stodola
更新了您的答案,包括SEO链接,并确认库使用反射。 - Josh Stodola
Copyable 没有提到的一个注意事项是,像它这样的类不知道数据结构中的外部引用。例如,假设在一个类中有一个对 String 的单元素数组的引用,并且假设每秒钟另一个类将当前时间放入该数组的第一个(唯一)元素中。原始类对象的克隆将包含一个字符串,其中包含对象被复制时的时间,而不是一个不断变化的时间。 - supercat
你可以使用映射器,我建议使用UltraMapper https://github.com/maurosampietro/UltraMapper。它使用表达式树而不是反射,因此比反射快1000倍。 - Mauro Sampietro

2

一个建议是使用Json序列化(它使用反射,不依赖于[Serializable]属性)将对象序列化和反序列化为副本。例如,使用Json.Net库:

var copiedObject = JsonConvert.DeserializeObject<Snapshot>(
    JsonConvert.SerializeObject(sourceSnapshotObject));

0

你不能这样做(或者也许不应该这样做)。

如果类没有被设计成可序列化的,并且它没有提供克隆它的方法(例如 clone 或 copy 方法),那么你就不能轻易地自动完成这个任务。(而且,如果没有提供这种功能,那么你可能不应该这样做,因为这个类可能没有考虑到这种用法。)

然而,如果你真的想这样做,并且你处于完全信任的环境中,那么当然可以使用 FormatterServices.GetUninitializedObject 来进行一些肮脏的操作,然后使用反射将一个对象的字段值复制到另一个对象中。但这几乎肯定是一个坏主意。


我没有点踩,但我认为你应该看看Kenny的回答。 - user47589

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接