我想知道为什么将MemberwiseClone定义为受保护。这意味着只有派生类型才能访问它。如果将其定义为公共问题会有什么问题?
答案 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: