This is the last creational pattern in this series. And it’s used to create clones of objects without using references. C# is giving us helpful method MemberwiseClone() that is doing all cloning in the background. Later in the article I’ll cover the difference between Shadow and Deep Cloning.
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.
In my example I’m creating copy of the Enemy object that will keep the same ID as the base object.
UML diagram
Prototype
First thing to do is the interface that will be implemented by concrete class. This is an interface which is used for the types of object that can be cloned itself.
public abstract class AbstractEnemy
{
int _id;
public int Id
{
get { return _id; }
set { _id = value; }
}
public abstract AbstractEnemy Clone();
}
This time implementation will be very simple thank to the MemberwiseClone() method.
class Enemy : AbstractEnemy
{
public override AbstractEnemy Clone()
{
Console.WriteLine("cloning enemy...");
return this.MemberwiseClone() as AbstractEnemy;
}
}
One last thing to create is the Client Class that will create instance of an enemy and perform the cloning procedure.
Client
~~~ c#
static void Main(string[] args)
{
Enemy enemy = new Enemy();
enemy.Id = 1;
Console.WriteLine("Enemy Copy ID: " + enemy.Id.ToString());
Enemy clonedEnemy = enemy.Clone() as Enemy;
Console.WriteLine("Enemy Copy ID: " + clonedEnemy.Id.ToString()); } } ~~~
Difference between Shadow and Deep Cloning
The problem with the memberwise copy is that it creates a shallow copy of the object i.e. if the object contains any reference types then only the address of that reference type will be copied from source to target and both the versions will keep pointing to the same object. Changing properties of inner-class of one object will change them for other class as well.
-
A shallow copy copies all reference types or value types, but it does not copy the objects that the references refer to. The references in the new object point to the same objects that the references in the original object points to.
-
Deep copy of an object copies the elements and everything directly or indirectly referenced by the elements.
Solution to this problem is to create new Copy() method that will involve copying the inner class properties to new object. or to include copy() method to all object sub classes, just as it was implemented in previous example.
~~~ c#
public override AbstractEnemy Clone() { Enemy cloned = this.MemberwiseClone() as Enemy; cloned.Equipment = new Equipment(); cloned.Equipment.Armor = this.Equipment.Armor;
return cloned as AbstractEnemy; } ~~~
To conclude, this pattern specifies the kind of objects to create using a prototypical instance, and create new objects by copying this prototype. I hope you learned something new. In next series of articles I’ll start moving into low level languages. Stay Awesome!