using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using XmlReader;
using System.Threading;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Expression;
using System.Reflection;
namespace RunComObject
{
/// <summary>
/// Description: Util class to copy properties from source object to another/new object
/// Create Date: 2009-06-26
/// Author: Rock Niu
/// </summary>
public sealed class PropertyCopyer
{
/// <summary>
/// Copy from source object to a new object
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static T CopyFrom<T>(object sourceObject) where T : class, new()
{
T targetObject = new T();
InternalCopy(ref targetObject, sourceObject);
return targetObject;
}
/// <summary>
/// Copy properties from source object to target object but not change target object reference.
/// </summary>
/// <typeparam name="TTarget"></typeparam>
/// <typeparam name="TSource"></typeparam>
/// <param name="targetObject"></param>
/// <param name="sourceObject"></param>
public static void CopyFrom<TTarget, TSource>(TTarget targetObject, TSource sourceObject)
where TTarget : class, new()
where TSource : class, new()
{
InternalCopy(ref targetObject, sourceObject);
}
private static void InternalCopy<TTarget, TSource>(ref TTarget targetObject, TSource sourceObject)
where TTarget : class, new()
where TSource : class, new()
{
Type sourceType = sourceObject.GetType();
Type targetType = targetObject.GetType();
PropertyInfo[] sourceProperties = sourceType.GetProperties();
if (sourceProperties == null)
{
throw new Exception("Existing object has no property!");
}
foreach (PropertyInfo info in sourceProperties)
{
Object value = info.GetValue(sourceObject, null);
PropertyInfo targetProperty = targetType.GetProperty(info.Name);
if (targetProperty == null)
{
throw new Exception("Property '" + info.Name + "' not found in target type'" + targetType.FullName + "'.");
}
if (!targetProperty.CanWrite)
{
throw new Exception("Property '" + info.Name + "' in target type'" + targetType.FullName + "' is read only.");
}
targetProperty.SetValue(targetObject, value, null);
Debug.WriteLine("Setting property: " + info.Name + ", value: " + (value==null? “<NULL>”: value.ToString()) );
}
}
}
public class Entity
{
public int Id { get; set; }
public String Name { get; set; }
internal DateTime Age { get; set; }
}
public class Entity2
{
public int Id { get; set; }
public String Name { get; set; }
public DateTime Age { get; set; }
public override string ToString()
{
return string.Format("Id={0},Name={1},Age={2}", Id, Name, Age);
}
}
class Program
{
static void Main(string[] args)
{
var e = new Entity() { Id = 1, Name = "Rock", Age = DateTime.Today };
var x = PropertyCopyer.CopyFrom<Entity2>(e);
Console.WriteLine(x);
Debug.Assert(!Object.ReferenceEquals(x, e));
var e2= new Entity2();
e.Id = 999;
PropertyCopyer.CopyFrom(e2, e);
Entity2 e3 = e2;
PropertyCopyer.CopyFrom(e2, e);
Debug.Assert(!Object.ReferenceEquals(e2, e));
Debug.Assert(Object.ReferenceEquals(e2, e3));
Console.WriteLine(e2);
Console.Read();
}
}
}