using System;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace Masuit.Tools.Mapping
{
///
/// 表达式树复制对象
///
///
public static class Copier
{
private static readonly ParameterExpression ParameterExpression = Expression.Parameter(typeof(T), "p");
private static Func _func;
private static readonly Dictionary DictRule = new Dictionary();
///
/// 深拷贝
///
///
///
public static T Copy(T source)
{
if (_func != null)
{
return _func.Invoke(source);
}
var memberBindings = new List();
foreach (var item in typeof(T).GetProperties())
{
if (DictRule.ContainsKey(item.Name))
{
MemberBinding memberBinding = Expression.Bind(item, DictRule[item.Name]);
memberBindings.Add(memberBinding);
}
else
{
var tInProperty = typeof(T).GetProperty(item.Name);
var tInField = typeof(T).GetField(item.Name);
if (tInProperty != null || tInField != null)
{
MemberExpression property = Expression.PropertyOrField(ParameterExpression, item.Name);
MemberBinding memberBinding = Expression.Bind(item, property);
memberBindings.Add(memberBinding);
}
}
}
foreach (var item in typeof(T).GetFields())
{
if (DictRule.ContainsKey(item.Name))
{
MemberBinding memberBinding = Expression.Bind(item, DictRule[item.Name]);
memberBindings.Add(memberBinding);
}
else
{
var tInProperty = typeof(T).GetProperty(item.Name);
var tInField = typeof(T).GetField(item.Name);
if (tInProperty != null || tInField != null)
{
MemberExpression property = Expression.PropertyOrField(ParameterExpression, item.Name);
MemberBinding memberBinding = Expression.Bind(item, property);
memberBindings.Add(memberBinding);
}
}
}
var memberInitExpression = Expression.MemberInit(Expression.New(typeof(T)), memberBindings.ToArray());
var lambda = Expression.Lambda>(memberInitExpression, ParameterExpression);
_func = lambda.Compile();
return _func.Invoke(source);
}
}
}