Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / WPF

Simple Properties Mapper by Reflection: Stop Copying Manually Each Property of Your Objects !

5.00/5 (2 votes)
9 Apr 2010Ms-PL2 min read 1  
Simple properties Mapper by reflection: Stop copying manually each property of your objects !

There are times 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 does 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 its instance: just clone it as a snapshot and copy back the properties when you want.
  • You get some Data Transfer Object coming from WCF/Web services and you want 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 implement.

Let's Jump to the Code !

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

I use reflection to obtain every property of the source and then I check on the target if a property exists 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 names which will be ignored by the "copy process".

With a little more time, you can also add a dictionary which may map a property name in the source to another property name in the target if the names are noted to be exactly the same...

C#
public static class PropetiesMapper{
    /// <summary>
    /// Copies all the properties of the "from" object to this object if they exist.
    /// </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 properties 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)
        {
          //Copy 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 exist.
    /// </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 properties 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 a "Hand made" label on your object's mapping ? :-D

A More Complex and Complete Tool

For those who want something more powerful and complete, take a look at the automapper library on CodePlex.

Shout it kick it on DotNetKicks.com

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)