当要更新一个对象A的某些字段,但又要保留这个对象A的数据,以便后续给其他对象C赋值时,就得将这个对象copy给一个同类对象B,然后update这个同类对象B。但是手动将对象A的所有字段赋给对象B,太麻烦了(尤其是字段太多的情况下),此时就可以在Util项目中添加以下这个ClassCopy.cs
public static class ClassCopy
{
static ConcurrentDictionary<string, object> actions = new ConcurrentDictionary<string, object>();
static Action<S, T> CreateCopier<S, T>()
{
var target = Expression.Parameter(typeof(T));
var source = Expression.Parameter(typeof(S));
var props1 = typeof(S).GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(p => p.CanRead).ToList();
var props2 = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(p => p.CanWrite).ToList();
var props = props1.Where(x => props2.Where(y => y.Name == x.Name).Count() > 0);
var block = Expression.Block(from p in props select Expression.Assign(Expression.Property(target, p.Name), Expression.Property(source, p.Name)));
return Expression.Lambda<Action<S, T>>(block, source, target).Compile();
}
public static T ShadowCopy<T>(this T original) where T : class, new()
{
T target = new T();
string name = string.Format("{0}", typeof(T));
object obj;
if (!actions.TryGetValue(name, out obj))
{
var ff = CreateCopier<T, T>();
actions.TryAdd(name, ff);
obj = ff;
}
Action<T, T> act = (Action<T, T>)obj;
act(original, target);
return target;
}
}
用法:
wiplotsts = wiplotsts2.ShadowCopy();
==========原始的做法