为什么System.Object中定义的MemberwiseClone受到保护?

时间:2010-07-17 16:42:17

标签: .net

我想知道为什么将MemberwiseClone定义为受保护。这意味着只有派生类型才能访问它。如果将其定义为公共问题会有什么问题?

4 个答案:

答案 0 :(得分:4)

Pavel Minaev's answer from another discussion:

其他人已经解释过有关MemberwiseClone的问题,但是没有人解释为什么它受到保护。我会尽力给出理由。

这里的问题是,MemberwiseClone只是盲目地复制状态。在许多情况下,这是不可取的。例如,对象可能具有私有字段,该字段是对List的引用。一个浅的副本,比如MemberwiseClone所做的那样,会导致新的对象指向同一个列表 - 并且可能会编写类而不期望列表与其他任何人共享。

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

或者说你有一个打开套接字或文件流的对象,并存储对它的引用。 MemberwiseClone将只复制引用 - 您可以想象试图将调用交错到同一个流的两个对象不会很好地结束。

简而言之,“克隆”不是任意对象的明确定义的操作。默认情况下,在C ++中为所有类提供成员operator =这一事实更令人讨厌,因为人们常常忘记它在那里,并且不会为复制没有意义的类禁用它,或者是危险的(并且有很多这样的课程。)

答案 1 :(得分:4)

  • 很多事情没有意义被克隆;与非托管句柄对话的任何内容,例如
  • 大多数对象不需要克隆设施
  • 如果你超出一些简单的案例,那么正确地 非常
  • 在许多情况下,有比盲人克隆更好的隐喻
  • 手动将克隆工具添加到需要它的类型非常简单

对我来说,默认情况下, 应该添加到公共API中,这是明智的。

答案 2 :(得分:1)

答案 3 :(得分:0)

从字面上看,没有人阻止您在自己的课堂上公开露面。这在很大程度上取决于您要实现的目标。例如,MemberwiseClone它不执行任何ctor。因此,使用Activator.CreateInstance会更有用。

考虑到MemberwiseClone的实际作用,几乎在每种情况下都不需要公开它。

protected unsafe object MemberwiseClone()
{
    object clone = RuntimeHelpers.AllocateUninitializedClone(this);
 
    // copy contents of "this" to the clone
    nuint byteCount = RuntimeHelpers.GetRawObjectDataSize(clone);
    ref byte src = ref this.GetRawData();
    ref byte dst = ref clone.GetRawData();
 
    if (RuntimeHelpers.GetMethodTable(clone)->ContainsGCPointers)
        Buffer.BulkMoveWithWriteBarrier(ref dst, ref src, byteCount);
    else
        Buffer.Memmove(ref dst, ref src, byteCount);
    return clone;
}

您可以找到它here