I'm wondering why MemberwiseClone is defined as protected. This means that only derived types can access it. What is the problem if it was defined as public?
4 Answers
Pavel Minaev's answer from another discussion:
Others have already explained about MemberwiseClone, but no-one gave the explanation of why it is protected. I'll try to give the rationale.
The problem here is that MemberwiseClone just blindly copies the state. In many cases, this is undesirable. For example, the object might have a private field which is a reference to a List. A shallow copy, such as what MemberwiseClone does, would result in new object pointing to the same list - and the class may well be written not expecting the list to be shared with anyone else.
Or an object can have some sort of ID field, generated in constructor - again, when you clone that, you get two objects with the same ID, which may lead to all kinds of weird failures in methods assuming that ID is unique.
Or say you have an object that opens a socket or a file stream, and stores a reference to that. MemberwiseClone will just copy the reference - and you can imagine that two objects trying to interleave calls to the same stream isn't going to end well.
In short, "cloning" is not a well-defined operation for arbitrary objects. The fact that memberwise operator= is provided for all classes by default in C++ is more of a nuisance, as all too often people forget that it's there, and do not disable it for classes for which copying doesn't make sense, or is dangerous (and there are surprisingly many such classes).
-
2Next time it is worth just marking the question as a duplicate rather than copy and pasting answers. – S1r-Lanzelot Jun 26 '18 at 13:24
- A lot of things don't make sense to be cloned; anything that talks to an unmanaged handle, for example
- Most objects do not need a clone facility
- Deep-copying something properly is really hard if you go outside of a few simple cases
- In many cases, there are better metaphors than blind clones
- Manually adding a clone facility to your types that need it is trivially easy
To me, then, it is a no-brainer that this should not be added to the public API by default.

- 1,026,079
- 266
- 2,566
- 2,900
If MemberwiseClone didn't exist, there would be no means, other than by using Reflection, for any inheritable class to support a polymorphic cloning operation, except by requiring every derived class to explicitly provide one. Failure of a derived class to provide a cloning operation would result in unexpected behavior. For example, suppose Vehicle, Car, and ToyotaCar provide explicit cloning methods, but ToyotaCorolla does not. If someone has an object of type ToyotaCorolla and tries to clone it, the resulting object would be a ToyotaCar. Since there are situations where polymorphic cloning is required, and it would be inconvenient to require every derived class of a clonable class to provide explicit support, MemberwiseClone is a necessary part of the framework.
On the other hand, MemberwiseClone can also be dangerous. Performing a MemberwiseClone on an object will frequently yield a broken object; attempting using any properties or methods of the broken object may corrupt the original.
It's too bad Microsoft didn't better define a good practice for cloning. It's possible, and not overly difficult, to design a polymorphic cloning pattern which doesn't require inherited classes to explicitly do anything unless they add fields which require special handling, or unless a caller will expect the declared return type of the Clone method's to be the derived class. While the latter situation will frequently be a requirement, failure to explicitly implement the necessary method will yield a compile-time error, rather than buggy run-time behavior.
BTW, Microsoft seems to think there's something confusing about deep vs. shallow cloning. There isn't. Calling "Clone" on an object should clone the object to whatever depth is necessary to obtain its defined semantics. Cloning a FileCabinet(Of T) should yield a new FileCabinet which is, for purposes of the methods of FileCabinet, independent of the original, but it should hold the same instances of T as the original. Since the purpose of a file cabinet is to hold instances of T, but not to do anything with them, cloning the cabinet should not imply cloning the contents (but it would imply cloning any arrays which the Cabinet itself uses to hold the contents).
BTW, if I had my druthers there would be an interface in .Net, implemented by String and primitive types (plus many others), called DeepClonableIfMutable. When applied to a String or other primitive, the DeepCloneIfMutable method would simply return the original object. User-defined immutable objects could implement DeepClonableIfMutableto behave similarly, while mutable objects would deep-clone themselves and any nested DeepClonableIfMutable instances.

- 77,689
- 9
- 166
- 211
Literally noone is preventing you from exposing it as public in your own class if you want to. It highly depends on what you want to achieve. For example MemberwiseClone it does not execute any ctor. So it would be more usefull to use Activator.CreateInstance.
Considering what MemberwiseClone actually does, there is in almost every case no need to expose it.
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;
}
you can find it here:

- 2,406
- 1
- 10
- 35