代码之家  ›  专栏  ›  技术社区  ›  juan

为什么克隆(在.NET中)如此困难?

  •  19
  • juan  · 技术社区  · 16 年前

    在过去,我需要克隆对象,结果发现它们没有实现 Clone() 方法,强制我手动执行(创建一个新实例并将所有属性从原始实例复制到新实例)

    为什么克隆不像复制分配给对象的内存块那样容易,从而获得 Clone 中的方法 object

    5 回复  |  直到 16 年前
        1
  •  25
  •   Jon Skeet    16 年前

    因为这不会执行深度克隆,这是 通常 克隆人真正需要的是什么。假设您有一个对数组或列表的引用。。。简单地复制 你的目标 将只克隆引用。对数组的任何更改都将通过克隆以及原始对象可见,因此这两个对象仍然是连接的,这违反了克隆的正常点。

    Object.MemberwiseClone() 这是给你的。大多数时候,如果它能 感觉 要克隆对象(克隆对象的作用是什么 NetworkStream 是什么意思?)克隆每个属性是有意义的。。。除非它已经引用了一个不可变的值,等等。换句话说,这是一个自然困难的问题,这就是为什么大多数类型不支持克隆。

    非常

        2
  •  8
  •   Pavel Minaev    16 年前

    MemberwiseClone ,但没有人对此作出解释 为什么? 它受到保护。我将试着给出理由。

    这里的问题是 MemberwiseClone List . 肤浅的复制品,比如什么 MemberwiseClone 则会导致新对象指向同一个列表,并且编写该类时可能不希望该列表与其他任何人共享。

    或者一个对象可以有某种类型的ID字段,在构造函数中生成——同样,当您克隆它时,您会得到两个具有相同ID的对象,这可能会导致假设ID是唯一的方法中出现各种奇怪的失败。

    或者说,您有一个打开套接字或文件流的对象,并存储对该对象的引用。 将只复制引用—您可以想象,两个对象试图交错调用同一个流不会有好的结果。

    简而言之,“克隆”并不是一种针对任意对象的定义良好的操作。事实是 operator=

        3
  •  4
  •   Patrick Huizinga    14 年前

    有(至少)两种克隆。大多数参考文献都谈到 浅的

    关键问题是“应该复制多少”和“应该共享多少”之间的紧张关系。

    考虑一个 Order Customer Address List 属于 OrderLines .

    如果你想 Clone() 涉及到什么?

    只是复制内存块 “我会给你一个新的 命令 ,但这是一个共享 , 地址 同样 属于 . (请记住,对象成员是通过引用存储的,因此当复制内存块时,最终会对同一对象进行两次引用)。

    很明显,你不想和别人分享 属于 订单线 介于两者之间 命令 s事实上,你可能想克隆每一个 OrderLine

    克隆() 方法,该方法如何知道哪些成员应该递归克隆,哪些不应该递归克隆?

    一般来说,这是一个棘手的问题——这就是为什么要由单个对象来实现 适合他们的情况的语义 .

    最后一点:即使我创造了 克隆() 克隆() 复制构造函数 -接受另一个对象作为基础的构造函数。如果你找不到 克隆() ,找那个。

        4
  •  2
  •   Jeff Meatball Yang    16 年前

    有这样一件事 Object.MemberwiseClone(), 和你描述的一样。它正在制作对象的浅拷贝。

    它不会自动进行深度克隆。。。您需要手动调用所有成员对象上的克隆,等等。

        5
  •  0
  •   devio    16 年前

    您必须显式地实现 ICloneable 类中的接口。

    然而,正如文件所述,克隆机制 MemberwiseClone 不区分浅拷贝和深拷贝。

    推荐文章