Home
Manage Your Code
Snippet: Type Transmogrifier / Converter (C#)
Title: Type Transmogrifier / Converter Language: C#
Description: Converts one type to another and copies matching properties across. Views: 126
Author: Glenn Bunter Date Added: 10/2/2007
Copy Code  
1/// <summary>

2	/// Allows one complex type to be converted to another, if both the property name and type match.

3	/// </summary>

4	/// <remarks>

5	/// http://en.wikipedia.org/wiki/Transmogrifier

6	/// </remarks>

7	public class TypeTransmogrifier
8	{
9		/// <summary>

10		/// Allows one complex type to be converted to another, if both the property name and type match.

11		/// </summary>

12		/// <remarks>

13		/// The target type must have a default contructor with no arguments, if it doesn't use the other method which allows contrustor args.

14		/// 

15		/// Note that the names must match exactly, yes it's case-sensitive.  Also the properties must be public and have get and set accessors, so 

16		/// pretty much the same requirements as for XML Serialisation.

17		/// </remarks>

18		/// <param name="source"></param>

19		/// <param name="targetType"></param>

20		/// <returns></returns>

21		public static object Transmogrify( object source, Type targetType )
22		{
23			return Transmogrify( source, targetType, new object[] { } );	
24 		}
25		/// <summary>

26		/// Allows one complex type to be converted to another, if both the property name and type match.

27		/// </summary>

28		/// <remarks>

29		/// Note that the names must match exactly, yes it's case-sensitive.  Also the properties must be public and have get and set accessors, so 

30		/// pretty much the same requirements as for XML Serialisation.

31		/// </remarks>

32		/// <param name="source"></param>

33		/// <param name="targetType"></param>

34		/// <param name="constructorArgs"></param>

35		/// <returns></returns>

36		public static object Transmogrify( object source, Type targetType, params object[] constructorArgs )
37		{
38			Type sourceType = source.GetType();
39
40			//Get the properties of both types.

41
42			PropertyInfo[] sourceTypeProperties = sourceType.GetProperties();
43
44			PropertyInfo[] targetTypeProperties = targetType.GetProperties();
45
46			//Create an instance of the targetType

47			object target = Activator.CreateInstance( targetType, constructorArgs );
48
49			foreach ( PropertyInfo sourceTypeProperty in sourceTypeProperties )
50			{
51				foreach ( PropertyInfo targetTypeProperty in targetTypeProperties )
52				{
53					if ( sourceTypeProperty.Name == targetTypeProperty.Name &&
54						sourceTypeProperty.PropertyType == targetTypeProperty.PropertyType )
55					{
56						object sourcePropertyValue = sourceType.InvokeMember(
57							sourceTypeProperty.Name,
58							BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty,
59							null,
60							source,
61							new object[] { } );
62
63						targetType.InvokeMember(
64							targetTypeProperty.Name,
65							BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty,
66							null,
67							target,
68							new object[] { sourcePropertyValue } );
69					}
70				}
71			}
72
73			return target;
74		}
75	}
Usage
Reference System.Reflection.

Notes
Read the code comments.