Proper way to implement ICloneable
.net, c#, icloneable, oop
Solution
You can easily create a superficial clone with `object`'s protected method MemberwiseClone.
Example:
public abstract class AbstractCloneable : ICloneable
{
public object Clone()
{
return this.MemberwiseClone();
}
}
If you don't need anything like a deep copy, you will not have to do anything in the child classes.
The MemberwiseClone method creates a shallow copy by creating a new object, and then copying the nonstatic fields of the current object to the new object. If a field is a value type, a bit-by-bit copy of the field is performed. If a field is a reference type, the reference is copied but the referred object is not; therefore, the original object and its clone refer to the same object.
If you need more intelligence in the cloning logic, you can add a virtual method to handle references :
public abstract class AbstractCloneable : ICloneable
{
public object Clone()
{
var clone = (AbstractCloneable) this.MemberwiseClone();
HandleCloned(clone);
return clone;
}
protected virtual void HandleCloned(AbstractCloneable clone)
{
//Nothing particular in the base class, but maybe useful for children.
//Not abstract so children may not implement this if they don't need to.
}
}
public class ConcreteCloneable : AbstractCloneable
{
protected override void HandleCloned(AbstractCloneable clone)
{
//Get whathever magic a base class could have implemented.
base.HandleCloned(clone);
//Clone is of the current type.
ConcreteCloneable obj = (ConcreteCloneable) clone;
//Here you have a superficial copy of "this". You can do whathever
//specific task you need to do.
//e.g.:
obj.SomeReferencedProperty = this.SomeReferencedProperty.Clone();
}
}
Problem
What is the proper way of implementing `ICloneable` in a class hierarchy? Say I have an abstract class `DrawingObject`. Another abstract class `RectangularObject` inherits from `DrawingObject`. Then there are multiple concrete classes like `Shape`, `Text`, `Circle` etc. that all inherit from `RectangularObject`. I want to implement `ICloneable` on `DrawingObject` and then carry it down the hierarchy, copying available properties at each level and calling parent's `Clone` at the next level. The problem however is that since the first two classes are abstract, I cannot create their objects in the `Clone()` method. Thus I must duplicate the property-copying procedure in each concrete class. Or is there a better way?