• 比AutoMapper更强的 表达式通用映射器 ExpressionGenericMapper


    using System;
    using System.Collections.Concurrent;
    using System.Collections.Generic;
    using System.Linq.Expressions;
    
    namespace Guma.StudyNotes.ExpressionExtend.Utils
    {
        /// <summary>
        /// 表达式通用映射器
        /// </summary>
        /// <remarks>@Auth: Guma;@Website: www.1995v.com</remarks>
        /// <typeparam name="TIn">传入类型:不能为集合类型,会引发 ParameterCannotCollectionException 异常</typeparam>
        /// <typeparam name="TOut">返回类型:不能为集合类型,会引发 ParameterCannotCollectionException 异常</typeparam>
        public static class ExpressionGenericMapper<TIn, TOut> where TIn : class, new() where TOut : class, new()
        {
            private static Func<TIn, TOut> _func = null;
            static ExpressionGenericMapper()
            {
                if (typeof(TIn).Namespace.Contains("System.Collections"))
                {
                    throw new ParameterCannotCollectionException();
                }
                else
                {  
                    ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn), "p");
                    List<MemberBinding> memberBindingList = new List<MemberBinding>();
    
                    foreach (var item in typeof(TOut).GetProperties())
                    {
                        if (item.SetMethod != null)
                        {
                            MemberExpression property = Expression.Property(parameterExpression, typeof(TIn).GetProperty(item.Name));
                            MemberBinding memberBinding = Expression.Bind(item, property);
                            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);
                        memberBindingList.Add(memberBinding);
                    }
    
                    MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TOut)), memberBindingList.ToArray());
                    Expression<Func<TIn, TOut>> lambda = Expression.Lambda<Func<TIn, TOut>>(memberInitExpression, new ParameterExpression[]
                    {
                        parameterExpression
                    });
    
                    _func = lambda.Compile();
                }
            }
    
            #region Overloading Methods
    
            public static TOut Trans(TIn t)
            {
                return _func(t);
            }
    
            public static List<TOut> Trans(List<TIn> t)
            {
                List<TOut> lstTout = new List<TOut>();
    
                foreach (var item in t)
                {
                    lstTout.Add(_func(item));
                }
    
                return lstTout;
            }
    
            public static Dictionary<T, TOut> Trans<T>(Dictionary<T, TIn> t)
            {
                Dictionary<T, TOut> mapTout = new Dictionary<T, TOut>();
    
                foreach (var item in t)
                {
                    mapTout.Add(item.Key, _func(item.Value));
                }
    
                return mapTout;
            }
    
            public static Stack<TOut> Trans(Stack<TIn> t)
            {
                Stack<TOut> stackout = new Stack<TOut>();
    
                foreach (var item in t)
                {
                    stackout.Push(_func(item));
                }
    
                return stackout;
            }
    
            public static Queue<TOut> Trans(Queue<TIn> t)
            {
                Queue<TOut> queuekout = new Queue<TOut>();
    
                foreach (var item in t)
                {
                    queuekout.Enqueue(_func(item));
                }
    
                return queuekout;
            }
    
            public static ConcurrentBag<TOut> Trans(ConcurrentBag<TIn> t)
            {
                ConcurrentBag<TOut> bagout = new ConcurrentBag<TOut>();
    
                foreach (var item in t)
                {
                    bagout.Add(_func(item));
                }
    
                return bagout;
            }
    
            public static ConcurrentDictionary<T, TOut> Trans<T>(ConcurrentDictionary<T, TIn> t)
            {
                ConcurrentDictionary<T, TOut> mapout = new ConcurrentDictionary<T, TOut>();
    
                foreach (var item in t)
                {
                    mapout.TryAdd(item.Key, _func(item.Value));
                }
    
                return mapout;
            }
    
            public static ConcurrentQueue<TOut> Trans(ConcurrentQueue<TIn> t)
            {
                ConcurrentQueue<TOut> queueout = new ConcurrentQueue<TOut>();
    
                foreach (var item in t)
                {
                    queueout.Enqueue(_func(item));
                }
    
                return queueout;
            }
    
            public static ConcurrentStack<TOut> Trans(ConcurrentStack<TIn> t)
            {
                ConcurrentStack<TOut> stackout = new ConcurrentStack<TOut>();
    
                foreach (var item in t)
                {
                    stackout.Push(_func(item));
                }
    
                return stackout;
            }
    
            #endregion
    
            #region ExceptionList
    
            class ParameterCannotCollectionException : ApplicationException
            {
                private const string _message = "当前泛型不能为集合类型,请使用集合方式的重载方法";
    
                public ParameterCannotCollectionException(string message = _message) : base(message) { }
            }
    
            #endregion
        }
    }
  • 相关阅读:
    BZOJ 4802 欧拉函数(Pollard_Rho)
    Codeforces 804E The same permutation(构造)
    Codeforces 804D Expected diameter of a tree(树形DP+期望)
    BZOJ 3399 [Usaco2009 Mar]Sand Castle城堡(贪心)
    BZOJ 2430 [Poi2003]Chocolate(贪心+归并排序)
    BZOJ 1707 [Usaco2007 Nov]tanning分配防晒霜(扫描线+贪心+优先队列)
    BZOJ 1828 [Usaco2010 Mar]balloc 农场分配(贪心+线段树)
    BZOJ 1827 [Usaco2010 Mar]gather 奶牛大集会(树形DP)
    BZOJ 2697 特技飞行(贪心)
    BZOJ 4883 [Lydsy2017年5月月赛]棋盘上的守卫(最小生成环套树森林)
  • 原文地址:https://www.cnblogs.com/gcrmmh2/p/14462253.html
Copyright © 2020-2023  润新知