111,094
社区成员




/// <summary>
/// Expression Clone
/// </summary>
public static class DynamicCloneHandler<T> where T : class
{
/// <summary>
/// 初始化
/// </summary>
static DynamicCloneHandler()
{
CloneMethod = CreateCloneMethod();
}
/// <summary>
/// 克隆函数
/// </summary>
private static Action<T, T> CloneMethod;
/// <summary>
/// 创建克隆方法
/// </summary>
/// <param name="type">类型</param>
/// <returns></returns>
private static Action<T, T> CreateCloneMethod()
{
Type type = typeof(T);
ParameterExpression tTarget = Expression.Parameter(type, "TTarget"),
tSource = Expression.Parameter(type, "TSource");
List<BinaryExpression> LsExp = new List<BinaryExpression>(16);
foreach (FieldInfo field in type.GetFields(BindingFlags.Public | BindingFlags.Instance)
.Union(type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)))
{
MemberExpression originalMember = Expression.Field(tSource, field);
MemberExpression newMember = Expression.Field(tTarget, field);
BinaryExpression setValue = Expression.Assign(originalMember, newMember);
LsExp.Add(setValue);
}
BlockExpression body = Expression.Block(typeof(void), LsExp);
return Expression.Lambda<Action<T, T>>(body, tTarget, tSource).Compile();
}
/// <summary>
/// 克隆 instance
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="instance">clone目标对象</param>
/// <param name="CreateMethod">创建函数</param>
/// <returns></returns>
public static T Clone(T instance, Func<T> CreateMethod)
{
T newIns = CreateMethod();
CloneMethod(newIns, instance);
return newIns;
}
public static T Clone(T instance, T newIns)
{
CloneMethod(newIns, instance);
return newIns;
}
}
public class TestClass1 : ICloneable
{
public int ID { get; set; }
public string Name { get; set; }
public string Test;
public int Code { get { return Name.GetHashCode(); } }
public object Clone()
{
return DynamicCloneHandler<TestClass1>.Clone(this, () => new TestClass1());
}
}
public class TestClass2 : ICloneable
{
public int ID { get; set; }
public string Name { get; set; }
public string Test;
public int Code { get { return Name.GetHashCode(); } }
public object Clone()
{
return new TestClass2 { ID = ID, Test = Test, Name = Name };
}
}