There is time when you have to copy each property of an object to one another. This is called mapping and it's very fastidious to do it by hand.

In this post we'll see how to create a method extension which do it for you in one line of code !

When can it be useful

Here is a non exhaustive list of usage you can find to this snippet:

  • You want to reload the previous state of an object without changing it's instance : just clone it as a snapshot and copy back the properties when you want,
  • You get's some Data Transfert Object coming from WCF/Web services and you want's to fill a specific object with this data,
  • etc ...



I surely know this is not the most efficient way to solve these problems, but this is fast to use/understand and easy to implements.

Let's jump to the code !

What's inside ? Quite a few things actually ! There is two object, the source in which we take the data and the target in which we fill in these datas.

I use reflection to obtain every property of the source and then I check on the target if a property exist with the same name. If yes I fill it with the value of the property in the source object.

I also added a filter which is a list of Property name which will be ignored by the "copy process".

With a little more time you can also add a dictionnary which may map a property name in the source to an another property name in the target if the name are note exactly the same...

public static class PropetiesMapper{
	/// <summary>
    /// Copies all the properties of the "from" object to this object if they exists.
    /// </summary>
    /// <param name="to">The object in which the properties are copied</param>
    /// <param name="from">The object which is used as a source</param>
    /// <param name="excludedProperties">Exclude these proeprties from the copy</param>
    public static void copyPropertiesFrom(this object to, object from, string[] excludedProperties)
    {
 
      Type targetType = to.GetType();
      Type sourceType = from.GetType();
 
      PropertyInfo[] sourceProps = sourceType.GetProperties();
      foreach (var propInfo in sourceProps)
      {
        //filter the properties
        if (excludedProperties != null
          && excludedProperties.Contains(propInfo.Name))
          continue;
 
        //Get the matching property from the target
        PropertyInfo toProp =
          (targetType == sourceType) ? propInfo : targetType.GetProperty(propInfo.Name);
 
        //If it exists and it's writeable
        if (toProp != null && toProp.CanWrite)
        {
          //Copty the value from the source to the target
          Object value = propInfo.GetValue(from, null);
          toProp.SetValue(to,value , null);
        }
      }
    }
 
    /// <summary>
    /// Copies all the properties of the "from" object to this object if they exists.
    /// </summary>
    /// <param name="to">The object in which the properties are copied</param>
    /// <param name="from">The object which is used as a source</param>
    public static void copyPropertiesFrom(this object to, object from)
    {
      to.copyPropertiesFrom(from, null);
    }
 
    /// <summary>
    /// Copies all the properties of this object to the "to" object
    /// </summary>
    /// <param name="to">The object in which the properties are copied</param>
    /// <param name="from">The object which is used as a source</param>
    public static void copyPropertiesTo(this object from, object to)
    {
      to.copyPropertiesFrom(from, null);
    }
 
    /// <summary>
    /// Copies all the properties of this object to the "to" object
    /// </summary>
    /// <param name="to">The object in which the properties are copied</param>
    /// <param name="from">The object which is used as a source</param>
    /// <param name="excludedProperties">Exclude these proeprties from the copy</param>
    public static void copyPropertiesTo(this object from, object to, string[] excludedProperties)
    {
      to.copyPropertiesFrom(from, excludedProperties);
    }
  }



So, do you still want to put an "Hand made" label on your object's mapping ? :-D

A more complex and complete tool

For those which wants something more powerful and complete : take a look at the automapper library on codeplex.

Shout it kick it on DotNetKicks.com