gpt4 book ai didi

c# - 复杂第三方对象/类的深层复制

转载 作者:太空狗 更新时间:2023-10-29 19:45:17 29 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





Deep cloning objects

(51 个回答)


6年前关闭。




我一直在研究一个使用 PDFView4Net 创建 PDF 表单的项目。虽然库通常很好,但表单创建者在处理表单字段(即文本框、复选框等)时是原始的并且缺乏基本功能(例如复制/粘贴、对齐、格式设置等)。

问题 :我一直在扩展字段对象的功能,并在复制/粘贴时被绊倒。要做到这一点,我需要一个对象的深拷贝,而没有对原始对象的任何引用。我给供应商发了电子邮件,要求提供有关他们推荐的复制这些对象的方法的信息,他们回复说我需要手工制作每个属性的副本,手动......在 table 上拍脑袋。这些是大型类,具有多个嵌入类作为属性,以及 UI 元素。

问题 : 有没有什么好的方法可以为不需要序列化、不需要访问或更改源类并且不需要默认构造函数的复杂对象执行深层复制?

我尝试/审查的内容 :
我研究了各种方法来制作一个对象的深拷贝并一一丢弃:

  • 手动,通过艰苦的属性设置属性:我尝试使用 7 个字段对象中的第一个 (PDFTextBoxField),但它很快就因大量属性(也是不同类型的类)而失控。最后,我仍然对原始对象有挥之不去的引用,在那里它创建了一个浅拷贝,而不是按照预期的深拷贝。
  • 序列化:这些类没有被标记为可序列化,供应商也不会改变这一点。我问他们,他们说没有。
  • ICloneable:需要由供应商实现。
  • AutoMapper:这似乎用于将数据从一种或多种对象类型复制到另一种对象类型。我正在使用的对象是相同的类型。虽然我不反对使用它,如果它是最好的解决方案。
  • Emit Mapper:这个项目似乎已经被放弃了。
  • MemberwiseClone:做一个浅拷贝,而不是我正在寻找的深拷贝,尽管当提问者特别要求深拷贝时,很多其他帖子都建议这样做。
  • 值注入(inject)器:我从 ValueInjecter 实现了 FastDeepCloneInjection在 CodePlex 上,但需要从中注入(inject)的大多数类没有 0 参数构造函数,这是为副本创建新实例时所必需的。 ValueInjecter 不允许跳过某些属性,或者我只会跳过没有默认构造函数的项目并将它们设置为 null(默认值)。我在第一个类上就遇到了这个问题。为了解决这个问题,我创建了一个从原始类继承的包装类,并将原始类转换为包装类(反之亦然),但我认为这不是一个好的解决方案。

  • 编辑:我真的不觉得这个问题是重复的。我已经广泛搜索了解决方案,包括标记为重复/原始的帖子,但无法找到令人满意的解决方案。如上所述,我无权更改需要复制的类。这会降低 DataContractSerializer、BinaryFormatter 和任何其他类型的序列化。这也降低了我使用 Activator.CreateInstance 看到的反射示例,因为我需要复制的大约 95% 的类没有采用 0 个参数的构造函数。这与我在使用 ValueInjecter 时遇到的问题相同。这也是使用 ICloneable 的折扣。

    最佳答案

    我会为此使用 AutoMapper。考虑以下类定义:(注意私有(private) ctor)

    public class Parent
    {
    public string Field1 { get; set; }
    public Level1 Level1 { get; set; }
    public static Parent GetInstance()
    {
    return new Parent() { Field1 = "1", Level1 = new Level1 { Field2 = "2", Level2 = new Level2() { Field3 = "3"}}};
    }
    private Parent() { }
    }

    public class Level1
    {
    public string Field2 { get; set; }
    public Level2 Level2 { get; set; }
    }

    public class Level2
    {
    public string Field3 { get; set; }
    }

    然后,您可以根据需要将 AutoMapper 设置为深度克隆:
    [TestMethod]
    public void DeepCloneParent()
    {
    Mapper.CreateMap<Parent, Parent>();
    Mapper.CreateMap<Level1, Level1>();
    Mapper.CreateMap<Level2, Level2>();
    var parent = Parent.GetInstance();

    var copy = Mapper.Map<Parent, Parent>(parent);

    Assert.IsFalse(copy == parent);//diff object
    Assert.IsFalse(copy.Level1 == parent.Level1);//diff object
    Assert.IsFalse(copy.Level1.Level2 == parent.Level1.Level2);//diff object
    Assert.AreEqual("1", copy.Field1);
    Assert.AreEqual("2", copy.Level1.Field2);
    Assert.AreEqual("3", copy.Level1.Level2.Field3);
    }

    关于c# - 复杂第三方对象/类的深层复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28729683/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com