August 2006 - Posts

Clone a class by using MemberwiseClone method

I am currently working on a project that I accepted to "continue" because the original freelance programmer left the project without completing it. The project was started using VB.NET, and as the company requested, I am now converting it to C# before I go ahead to completing it.

While I'm doing the conversion, I've seen many parts in the codes that are in need of attention. One that I spotted quickly is how the project implemented the Clone method for all cloneable classes (making a copy of the instance rather, as opposed to referencing an instance using the equal (=) assignment operator).

Below is a shorter version how the implementation of a Profile class would look like, converted to C#:

public class Profile : ICloneable
{

 private string m_firstname;
 public string FirstName
 {
  get { return m_firstname; }
  set { m_firstname = value; }
 }

 private string m_lastname;
 public string LastName
 {
  get { return m_lastname; }
  set { m_lastname = value; }
 }

 private int m_age;
 public int Age
 {
  get { return m_age; }
  set { m_age = value; }
 }

 object ICloneable.Clone()
 {
  return this.Clone();
 }

 public Profile Clone()
 {
  Profile temp = new Profile();
  temp.FirstName = this.FirstName;
  temp.LastName = this.LastName;
  temp.Age = this.Age;

  return temp;
 }
}


The above class was purposely shortened, but as you may have imagined, the class has more properties than just FirstName, LastName, and Age, hence the more properties the Profile class have, the larger the implementation of the Clone method. Not very manageable.

The simpliest way to shorten the Clone method is to call the object's MemberwiseClone method, which is provided by .NET to make a shallow copy of an object's instance -- rather than one-by-one copying all the properties, as shown above.

Here's how the updated version would look like:

public class Profile : ICloneable
{
 private string m_firstname;
 public string FirstName
 {
  get { return m_firstname; }
  set { m_firstname = value; }
 }

 private string m_lastname;
 public string LastName
 {
  get { return m_lastname; }
  set { m_lastname = value; }
 }

 private int m_age;
 public int Age
 {
  get { return m_age; }
  set { m_age = value; }
 }

 object ICloneable.Clone()
 {
  return this.MemberwiseClone();
 }

 public Profile Clone()
 {
  return (Profile)this.MemberwiseClone();
 }
}

I am aware that MemberwiseClone uses reflection to make a shallow copy, therefore it won't copy publicly exposed variables.

Anyway, this will be another busy month for me -- work, work, work.

Posted by cvega with no comments