Explicit Deep Copy Interface

This can be used to clone an object. We can create our own interface IProtoType<T> and specify a method of DeepCopy which will remove the ambiguity we got from trying ICloneable but its would still mean traversing the object tree manually so the copy is done recursively.

If you want to clone rather look at the suggestions under the creational Prototype Pattern.

Example

Example classes Person and Address which implement IPrototype - the nice thing now with IPrototype is the API would return the given type so no casting is needed.

1
2
3
4
public interface IPrototype<T>
{
T DeepCopy();
}

The implementation would be

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class Person : IPrototype<Person>
{
public string FirstName;
public Address Address;

public Person(string firstName, Address address)
{
FirstName = firstName;
Address = address;
}

public Person DeepCopy()
{
return new Person(FirstName, Address.DeepCopy());
}

public override string ToString()
{
return $"{nameof(FirstName)}: {FirstName}, {nameof(Address)}: {Address}";
}
}

public class Address : IPrototype<Address>
{
public string StreetName;
public int HouseNumber;

public Address(string streetName, int houseNumber)
{
StreetName = streetName;
HouseNumber = houseNumber;
}

public Address DeepCopy()
{
return new Address(StreetName, HouseNumber);
}

public override string ToString()
{
return $"{nameof(StreetName)}: {StreetName}, {nameof(HouseNumber)}: {HouseNumber}";
}
}

Example usage:

1
2
3
4
5
6
7
8
var carl = new Person("Carl", new Address("Sale Street", 66));
var john = carl.DeepCopy();
john.FirstName = "John";
john.Address.HouseNumber = 456;
john.Address.StreetName = "Hoe Street";

Console.WriteLine(carl);
Console.WriteLine(john);

Output would be:

1
2
FirstName: Carl, Address: StreetName: Sale Street, HouseNumber: 66
FirstName: John, Address: StreetName: Hoe Street, HouseNumber: 456

References