欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

字典缓存表达式树

程序员文章站 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(),实现一定的性能提升,并且是泛型的。

相关标签: Asp.Net Core