Click here to Skip to main content
12,560,765 members (51,018 online)
Click here to Skip to main content
Add your own
alternative version


23 bookmarked

Generics and Cloning

, 12 Jun 2006 CPOL
Rate this:
Please Sign up or sign in to vote.
How to clone generic/template objects
Sample Image - 0g_GenericsAndCloning.jpg


In many applications, there is the need to track changes to the data presented to users. There are several approaches in achieving this. In this article, I cover an approach in which I use Cloning and Generics to be able to compare objects and determine if any changes have been made. The use of cloning is important because in some systems the instantiation of an object could be somewhat expensive. Cloning allows us to do a deep copy of the object already instantiated thus preventing the expensive process. Once the object is cloned, we can modify the cloned copy with the new information provided by the user and determine what changes have been made. In order to compare the objects, we need to override the Equals method from the Object class. The challenge with cloning is that we would like to know the object type and minimize the code sections required to do the cloning. In short, we would like to create a base class from which we can clone any object type. This is where Generics can help us.


To better understand this article, I recommend that the readers be somewhat familiar with the following concepts:

  • Generics
  • Cloning/ICloneable

The code for this article was written using .NET 2.0.

Using the Code

The first step is to create the CloneBase class (CloneBase.cs) which implements the ICloneable interface. This is needed to create a copy of object. Any class that implements this interface should also have the XML attribute [Serializable]. Not adding this attribute causes an exception to occur. This attribute must also be added to all the classes that inherit from the base class we are now creating. This takes care of the cloning part of the equation. Now, we need to be able to support different types. In order to do that, we need to declare the class as a template/generic definition by adding the generic type parameter <T>.

 public class CloneBase<T> : ICloneable 
   public CloneBase() { } 

The generic type parameter is needed because this is what is used to replace where the concrete type would be. In other words, when we need to return a clone of a certain type, T is replaced by such type. We will be able to see this with the implementation of the Clone method. Notice how this method has a return type of T.

public T Clone()
      T clone = default(T);        //initialize to default not null
            BinaryFormatter bf = new BinaryFormatter();     //helper to serialize
            MemoryStream memStream = new MemoryStream();    
            bf.Serialize(memStream, this);
            memStream.Position = 0;
            clone = ((T)bf.Deserialize(memStream));  //this returns the copy of type T
       catch (Exception ex)
            m_status = ex.Message;

       return clone;

This code serializes the object into a memory stream, which creates a copy of the object. It then deserializes the generic object by using the line of code below. We can notice the casting done using the generic type (T). The new object is then returned.

clone = ((T)bf.Deserialize(memStream));   //this returns the copy of type T   

We can now take a look at the client code which uses this base class. The project associated with this article has a Product class (Product.cs), which is used to represent a generic product. The class inherits from the CloneBase base class. Notice how this class too must have the XML attribute [Serializable]. This class also overrides the Equals method from the Object class. This is done to implement our own object comparison logic. In this case, we are comparing the value of all the data members. If any of the values is not the same, the code returns false.

 class Product : CloneBase<Product>
        //data members declared here

        public override bool Equals(object obj)
            bool bRtn = true;

            if (obj != null)
                Product objRef = (Product)obj;

                //simple object type comparison
                if (this.Name != objRef.Name ||  
			this.Description != objRef.Description ||
                    	this.Sku != objRef.Sku || this.Count != objRef.Count)
                    bRtn = false;
                bRtn = false;

            return bRtn;

We can now take a look at Windows form created for this article. This simple form displays all the data values for a Product object. When pressing the Save button, the application creates a clone of the object, assigns the values from the form to the clone, and compares the original object with the clone.

private void btnSave_Click(object sender, EventArgs e)
            Product clone = _prod.Clone();                //create clone

            if (clone != null)
                UIValues(clone, false);            //get current UI values;
                //check to see if any changes
                if (_prod.Equals(clone) == true)
                    MessageBox.Show("There is no change", this.Text); 
                    MessageBox.Show("There is a change", this.Text); 
                //did not clone!!! Use status to check for errors
                MessageBox.Show(_prod.Status, this.Text); 

Points of Interest

I have found the use of generics to be very useful. This was a great new feature of .NET 2.0. There are also many generic list classes which we can use to eliminate the use of classes like the ArrayList. I hope this article is useful to some of you. I look forward to getting your feedback.


  • 0g06012006: Initial version


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

ozkar garcia
Architect OG-BITechnologies
United States United States

You may also be interested in...


Comments and Discussions

GeneralMy vote of 5 Pin
ozkar garcia16-Feb-11 7:31
memberozkar garcia16-Feb-11 7:31 
GeneralUnusual approach... Pin
Pete Appleton19-Jun-06 22:32
memberPete Appleton19-Jun-06 22:32 
AnswerRe: Unusual approach... Pin
ozkar20-Jun-06 8:14
memberozkar20-Jun-06 8:14 
GeneralRe: Unusual approach... Pin
Pete Appleton20-Jun-06 23:03
memberPete Appleton20-Jun-06 23:03 
GeneralNo need for a base class [modified] Pin
leddt12-Jun-06 12:31
memberleddt12-Jun-06 12:31 
GeneralDownload file and image not accessible... Pin
Jun Du12-Jun-06 10:10
memberJun Du12-Jun-06 10:10 
GeneralRe: Download file and image not accessible... Pin
ozkar12-Jun-06 10:30
memberozkar12-Jun-06 10:30 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.161026.1 | Last Updated 12 Jun 2006
Article Copyright 2006 by ozkar garcia
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid