A friend of mine was showing me about some common interfaces and some good use cases for them the other day. A discussion arose of how to accurately create a deep copy of an object and the best way to go about it. Shortly after that discussion we got into the Sort() method and how to dictate how that method will sort your objects. This is when he spilled into telling me all about these common interfaces. So I decided to try to put together a good sample of these and the best way I could gather to implement them.
In this example we will create a Zoo object. Each Zoo object will contain a list of the Animal object. The Animal object will then be sub-classed into a Penguin and a Bear object. The overall goal will be to implement ICloneable class so that we can create either a deep or shallow copy of our Zoo object. Then we will implement IComparable on our Animal object so when we call the Sort() method on a list of Animal, it will be sorted by the class type name of the subclass and then by the name property of the Animal.
So first we will implement ICloneable on the Zoo class. Once setting it's inheritance, Visual Studio will show a smart tag when we mouse over the interface and give us the choice of implementing the interface or explicitly implementing the interface.
In this case, we are going to explicitly implement the ICloneable interface on the Zoo class. This is so that the ICloneable method implementation will be private to the Zoo object. The ICloneable.Clone() method returns a type of object, so we are going to box our Zoo object down to clone it and then return an unboxed, strongly typed Zoo object. By default we will return a deep copy of the Zoo object, but we will create an overload that will return a shallow copy just in case it is needed.
Before this can work, we will also have to implemented ICloneable on the Animal object.
Now we have Animal.Clone() and Zoo.Clone(). In the Zoo.Clone() method, to get a deep copy of all our objects we will create a new list of Animal and then clone each instance within our existing list of Animal and then add it to our new list. After that we can set that list of Animal to be the list contained within our new clone of Zoo. For a shallow copy of a Zoo object, we simply return a strongly typed MemberwiseClone.
Next we want to be able to sort our list of Animal by type name of its subclass and then by the name property of the Animal. To do this we will put a comma after the ICloneable inheritance call of the Animal class and then put IComparable after that. Now we will use our Visual Studio tab on mouseover of IComparable to implement this interface. Our implementation will look like this:
Next we will put a method in the Zoo object to sort our list of Animal.
Once put into a console program after creating a Zoo object, calling sort, creating a deep copy of it, using the deep copy to append the word "Copy" to each Animal's name property and the outputting the results, we get this:
That is all there is to it! The ability to create deep copies of objects and sort objects under your own terms is integral in programming. If you haven't used these before (like myself before a few days ago) keep these in mind when facing copy and sort problems in your programming.
Download the code:
SampleInterfaces.zip (33.51 kb)