If you expect your class to be inherited from (in code you don't
control) I would strongly suggest you avoid MemberwiseClone. You don't
know if the derived data can be safely be copied like that, or if it
for example references some unmanaged resource.
You're missing the point of MemberwiseClone then.
The correct way to clone a base-class object is as follows:
public virtual object Clone()
{
//perform shallow copies of all members, even derived ones
MyClass clone = (MyClass)MemberwiseClone();
//perform deep copies where required
clone.deepCopyValue = (ContainedClass)deepCopyValue.Clone();
//I usually disconnect any events here, actually
//since I don't usually want event handlers cloned
//finally
return clone;
}
This way any sub-classes of MyClass will automatically get a correct clone
of the base class. If the derived classes need a deep copy of anything
else, they can override Clone as follows:
public override object Clone() {
//allow base class to do its work, and deep copy anything it needs to
MySubClass clone = (MySubClass)base.Clone();
//if any of the derived members need to be deep-copied, do that here:
clone.collection = new MyCollection(collection);
return clone;
}
It's up to each class to deep-copy any members that it needs. If the
sub-class fails to do so, it's the fault of the sub-class. At least with
the base-class using MemberwiseClone, sub-classes don't need to override
Clone unless they need to provide further deep-copying. Many times,
shallow-copies are perfectly acceptable.
If you don't use this method, you either need to provide a means for
sub-classes to safely clone all of the members of the base class (by making
them protected, perhaps), or through the use of
copy-constructor-like-semmantics (which then require all sub-classes to
follow a pattern which isn't very intuative to most C# programmers).
Using any other method (especially methods where Clone isn't marked virtual)
makes it the job of every derived class to ensure that the base class is
cloned properly.
Using the method I've described makes it the job of each class to deep-copy
only the members that it needs to. Sub-classes need not worry about how to
clone the parent class. This helps versioning as well---in case the parent
class introduces new members that require deep copies that the child class
is not aware of.
It seems to me that NOT using MemberwiseClone is more fragile than using it.
Or am I missing some obvious better way to implement cloning? I know
copy-constructors can work, but it's not nearly as elegant as a virtual
Clone implemented with MemberwiseClone and further deep copying.
--Matthew W. Jackson