using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
/// <summary>
/// 反射加表达式树, 原文:
///<see>https://www.cnblogs.com/SF8588/p/16152078.html</see>
/// </summary>
public static class TransExp
{
private static Func<TIn, TOut> GetFunc<TIn, TOut>()
{
Type tin = typeof(TIn);
Type tout = typeof(TOut);
ParameterExpression parameterExpression = Expression.Parameter(tin, "p");
List<MemberBinding> memberBindingList = new List<MemberBinding>();
var list = tout.GetProperties();
for (int i = list.Length - 1; i > -1; --i)
{
var item = list[i];
if (!item.CanWrite) continue;
MemberExpression property = Expression.Property(parameterExpression, tin.GetProperty(item.Name));
MemberBinding memberBinding = Expression.Bind(item, property);
memberBindingList.Add(memberBinding);
}
var list2 = tout.GetFields();
for(int i = list2.Length - 1; i > -1; --i)
{
var item = list2[i];
MemberExpression property = Expression.Field(parameterExpression, tin.GetField(item.Name));
MemberBinding memberBinding = Expression.Bind(item, property);
memberBindingList.Add(memberBinding);
}
MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(tout), memberBindingList.ToArray());
Expression<Func<TIn, TOut>> lambda = Expression.Lambda<Func<TIn, TOut>>(memberInitExpression, new ParameterExpression[] { parameterExpression });
return lambda.Compile();
}
static Dictionary<Type, object> dic = new Dictionary<Type, object>();
/// <summary>
/// 只能拷贝类
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="T"></typeparam>
/// <param name="tIn"></param>
/// <returns></returns>
public static T Trans<T>(T tIn)
{
Type t = typeof(T);
Func<T, T> func;
if (dic.ContainsKey(t))
func = dic[t] as Func<T, T>;
else
{
func = GetFunc<T, T>();
dic.Add(t, func);
}
return func.Invoke(tIn);
}
static Dictionary<Type, object> dic2 = new();
public static TOut Trans<TIn, TOut>(TIn tIn)
{
Type t = typeof(Tuple<TIn, TOut>);
Func<TIn, TOut> func;
if (dic2.ContainsKey(t))
func = dic2[t] as Func<TIn, TOut>;
else
{
func = GetFunc<TIn, TOut>();
dic2.Add(t, func);
}
return func.Invoke(tIn);
}
}
表达式树深拷贝
最新推荐文章于 2024-07-19 08:56:24 发布