字典缓存表达式树
程序员文章站
2024-02-20 08:13:52
...
字典缓存表达式树
作用
动态的将TIn对象赋值给TOut对象, 条件是TIn和TOut中的字段和属性相同
直接看代码
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
namespace 字典缓存表达式树
{
public class ExpressionMapper
{
//字典缓存
private static Dictionary<string, object> _Dic = new Dictionary<string, object>();
/// <summary>
/// 字典缓存表达式树
/// 作用:动态的将TIn对象赋值给TOut对象, 条件是TIn和TOut中的字段和属性相同
/// </summary>
/// <typeparam name="TIn"></typeparam>
/// <typeparam name="TOut"></typeparam>
/// <param name="tIn"></param>
/// <returns></returns>
public static TOut Trans<TIn, TOut>(TIn tIn)
{
string key = string.Format($"function_{0}_{1}", typeof(TIn).FullName, typeof(TOut).FullName);
if(!_Dic.ContainsKey(key))
{
ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn), "p");
List<MemberBinding> memberBindingList = new List<MemberBinding>();
foreach(var item in typeof(TOut).GetProperties())
{
MemberExpression property = Expression.Property(parameterExpression,typeof(TIn).GetProperty(item.Name));
MemberBinding memberBinding = Expression.Bind(item,property);//TOut.age = TIn.age赋值, 映射表达式
memberBindingList.Add(memberBinding);
}
foreach (var item in typeof(TOut).GetFields())
{
MemberExpression property = Expression.Field(parameterExpression, typeof(TIn).GetField(item.Name));
MemberBinding memberBinding = Expression.Bind(item, property);//TOut.age = TIn.age赋值
memberBindingList.Add(memberBinding);
}
MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TOut)), memberBindingList.ToArray());//初始化表达式
Expression<Func<TIn,TOut>> expression = Expression.Lambda<Func<TIn, TOut>>(memberInitExpression,new ParameterExpression[] {
parameterExpression
});
Func<TIn, TOut> func = expression.Compile();
_Dic[key] = func;
}
return ((Func<TIn, TOut>)_Dic[key]).Invoke(tIn);
}
}
}
其中_Dic(字典缓存字段)的作用
它是静态变量,存储的是两个对象转化的委托实现。
分析
第一次调用该方法时,需要拼装表达式树。但第二次在调用时,_Dic字段里已经缓存了该委托方法,直接到Invoke(),实现一定的性能提升,并且是泛型的。