#143 – An Example of Implementing ICloneable for Deep Copies
November 7, 2010 10 Comments
Here’s an example of implementing ICloneable in two custom classes so that you can use the Clone method to do a deep copy.
To do a deep copy of the Person class, we need to copy its members that are value types and then create a new instance of Address by calling its Clone method.
public class Person : ICloneable { public string LastName { get; set; } public string FirstName { get; set; } public Address PersonAddress { get; set; } public object Clone() { Person newPerson = (Person)this.MemberwiseClone(); newPerson.PersonAddress = (Address)this.PersonAddress.Clone(); return newPerson; } }
The Address class uses MemberwiseClone to make a copy of itself.
public class Address : ICloneable { public int HouseNumber { get; set; } public string StreetName { get; set; } public object Clone() { return this.MemberwiseClone(); } }
Cloning a Person:
Person herClone = (Person)emilyBronte.Clone();
Great example Sean.
Pingback: deep copying userControl | BlogoSfera
Thanks a lot 😀
You nailed this one Sean!
Thanks David. :O)
Thanks, was very clear and usefull 🙂
What if instead of an Address object you had a list of Addresses? How would you copy them all? I was thinking about a for or a foreach but that would impact on performance.
You could use Array.Clone, or if List, do a foreach or implement an extension method like:
public static IList Clone(this IList listToClone) where T: ICloneable
{
return listToClone.Select(item => (T)item.Clone()).ToList();
}
Hey Sean,
Thanks for the example regarding the list above.
I have a ObservableCollection which has a Children property.
If I clone the list using the extension you provided, the list is cloned but if I modify any of its children, then the original ObservableCollection is modified as well.
e.g.
—–
var clonedList = ObjectCloner.SeanClone(list);
clonedList[0].Description = “test”; // original list in not affected
clonedList[0].Children[0].Description = “test” // this affects the original list
—–
I’m guessing I need some sort of recursion but I’m not getting anywhere
Something like:
—–
var clonedList = _CloneEverything(list);
—–
Any ideas what the content of _CloneEverything should be?
Thanks, Dave
It sounds like maybe you didn’t properly clone the child objects when implementing ICloneable?