Merge branch 'dev' of ssh://git.tuotong-tech.com:9105/tnb/tnb.server into dev
This commit is contained in:
76
common/Tnb.Common/Utils/DeepCopyHelper.cs
Normal file
76
common/Tnb.Common/Utils/DeepCopyHelper.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Tnb.Common.Utils
|
||||
{
|
||||
public class DeepCopyHelper<T> where T : class, new() // 需要无参构造函数,构造表达式树的时候需要利用无参构造函数创建对象
|
||||
{
|
||||
/// <summary>
|
||||
/// 映射表达式,泛型缓存每个类型存一份
|
||||
/// </summary>
|
||||
private static readonly Func<T, T> s_CopyFunc = null;
|
||||
|
||||
/// <summary>
|
||||
/// 静态构造函数,每个泛型类型会且只会执行一次
|
||||
/// </summary>
|
||||
static DeepCopyHelper()
|
||||
{
|
||||
BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
|
||||
ParameterExpression parameterExpression = Expression.Parameter(typeof(T), "m"); // 参数m :m =>
|
||||
List<MemberBinding> memberBindingList = new List<MemberBinding>();
|
||||
foreach (var item in typeof(T).GetProperties(bindingFlags))
|
||||
{
|
||||
if (!item.CanWrite) // 只读属性不拷贝
|
||||
{
|
||||
continue;
|
||||
}
|
||||
MemberExpression property = Expression.Property(parameterExpression, item); // m.Name
|
||||
MemberBinding memberBinding = Expression.Bind(item, property); // Name = m.Name
|
||||
memberBindingList.Add(memberBinding);
|
||||
}
|
||||
foreach (var item in typeof(T).GetFields(bindingFlags))
|
||||
{
|
||||
MemberExpression property = Expression.Field(parameterExpression, item);
|
||||
MemberBinding memberBinding = Expression.Bind(item, property);
|
||||
memberBindingList.Add(memberBinding);
|
||||
}
|
||||
MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(T)), memberBindingList.ToArray());// new T() {Name = m.Name}
|
||||
Expression<Func<T, T>> lambda = Expression.Lambda<Func<T, T>>(memberInitExpression, new ParameterExpression[]
|
||||
{
|
||||
parameterExpression
|
||||
}); // m => new T() {Name = m.Name}
|
||||
|
||||
s_CopyFunc = lambda.Compile();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 对象拷贝(拷贝private/public:实例成员、属性、静态成员)
|
||||
/// </summary>
|
||||
/// <param name="data">源</param>
|
||||
/// <returns></returns>
|
||||
public static T DeepCopy(T data)
|
||||
{
|
||||
return s_CopyFunc(data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 集合拷贝(拷贝private/public:实例成员、属性、静态成员)
|
||||
/// </summary>
|
||||
/// <param name="data">源</param>
|
||||
/// <returns></returns>
|
||||
public static List<T> DeepCopyList(List<T> data)
|
||||
{
|
||||
if (data == null || data.Count < 1)
|
||||
{
|
||||
return Enumerable.Empty<T>().ToList();
|
||||
}
|
||||
return data.Select(a => DeepCopy(a)).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user