Click here to Skip to main content
15,868,016 members
Articles / Desktop Programming / WPF

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

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
9 Apr 2010Ms-PL2 min read 17.4K   10   4
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

This article was originally posted at http://blog.lexique-du-net.com/index.php

License

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


Written By
Software Developer http://wpf-france.fr
France (Metropolitan) France (Metropolitan)
Jonathan creates software, mostly with C#,WPF and XAML.

He really likes to works on every Natural User Interfaces(NUI : multitouch, touchless, etc...) issues.



He is awarded Microsoft MVP in the "Client Application Development" section since 2011.


You can check out his WPF/C#/NUI/3D blog http://www.jonathanantoine.com.

He is also the creator of the WPF French community web site : http://wpf-france.fr.

Here is some videos of the projects he has already work on :

Comments and Discussions

 
QuestionSmall addition Pin
Marcus Schommler2-Feb-15 23:35
Marcus Schommler2-Feb-15 23:35 
QuestionContract Killer Pin
CodingBruce17-Sep-12 21:46
CodingBruce17-Sep-12 21:46 
So a prior post stated you'd never do this on an enterprise solution... Right, you'd do it bigger!

There are times when you need to take your client contract objects and use them as server objects (hopping the transport barrier). This is exactly how you do that, except... you need to do it more robustly with a recursive deep copy on IEnumerable. Slow, heck yah! but light-speed faster than serialization/deserialization or calling a service.

There's a whole world of mapping this introduces... See automapper.org



Enjoy
-bruce


modified 18-Sep-12 4:57am.

GeneralLight duty only Pin
ArchAngel12312-Apr-10 13:56
ArchAngel12312-Apr-10 13:56 
GeneralRe: Light duty only [modified] Pin
jmix9012-Apr-10 19:53
jmix9012-Apr-10 19:53 

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.