ExpressionGenericMapper.cs 3.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq.Expressions;
  4. namespace Masuit.Tools
  5. {
  6. /// <summary>
  7. /// 生成表达式目录树 泛型缓存
  8. /// </summary>
  9. public static class ExpressionGenericMapper
  10. {
  11. private static object func;
  12. /// <summary>
  13. /// 高性能对象浅克隆映射
  14. /// </summary>
  15. /// <typeparam name="TSource"></typeparam>
  16. /// <typeparam name="TDestination"></typeparam>
  17. /// <param name="source"></param>
  18. /// <returns></returns>
  19. public static TDestination Map<TSource, TDestination>(this TSource source)
  20. {
  21. if (func is null) //如果表达式不存在,则走一遍编译过程
  22. {
  23. ParameterExpression parameterExpression = Expression.Parameter(typeof(TSource), "p");
  24. var memberBindingList = new List<MemberBinding>(); //表示绑定的类派生自的基类,这些绑定用于对新创建对象的成员进行初始化(vs的注解。太生涩了,我这样的小白解释不了,大家将就着看)
  25. foreach (var item in typeof(TDestination).GetProperties()) //遍历目标类型的所有属性
  26. {
  27. MemberExpression property = Expression.Property(parameterExpression, typeof(TSource).GetProperty(item.Name)); //获取到对应的属性
  28. MemberBinding memberBinding = Expression.Bind(item, property); //初始化这个属性
  29. memberBindingList.Add(memberBinding);
  30. }
  31. foreach (var item in typeof(TDestination).GetFields())
  32. {
  33. MemberExpression property = Expression.Field(parameterExpression, typeof(TSource).GetField(item.Name)); //获取到对应的字段
  34. MemberBinding memberBinding = Expression.Bind(item, property); //同上
  35. memberBindingList.Add(memberBinding);
  36. }
  37. MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TDestination)), memberBindingList.ToArray()); //初始化创建新对象
  38. Expression<Func<TSource, TDestination>> lambda = Expression.Lambda<Func<TSource, TDestination>>(memberInitExpression, parameterExpression);
  39. func = lambda.Compile();
  40. }
  41. return source == null ? default(TDestination) : ((Func<TSource, TDestination>)func)(source);
  42. }
  43. /// <summary>
  44. /// 集合映射
  45. /// </summary>
  46. /// <typeparam name="TSource"></typeparam>
  47. /// <typeparam name="TDestination"></typeparam>
  48. /// <param name="source"></param>
  49. /// <returns></returns>
  50. public static IEnumerable<TDestination> Map<TSource, TDestination>(this IEnumerable<TSource> source)
  51. {
  52. foreach (TSource s in source)
  53. {
  54. yield return s.Map<TSource, TDestination>();
  55. }
  56. }
  57. /// <summary>
  58. /// 集合映射
  59. /// </summary>
  60. /// <typeparam name="TSource"></typeparam>
  61. /// <typeparam name="TDestination"></typeparam>
  62. /// <param name="source"></param>
  63. /// <returns></returns>
  64. public static IEnumerable<TDestination> Map<TSource, TDestination>(this IList<TSource> source)
  65. {
  66. foreach (TSource s in source)
  67. {
  68. yield return s.Map<TSource, TDestination>();
  69. }
  70. }
  71. /// <summary>
  72. /// 集合映射
  73. /// </summary>
  74. /// <typeparam name="TSource"></typeparam>
  75. /// <typeparam name="TDestination"></typeparam>
  76. /// <param name="source"></param>
  77. /// <returns></returns>
  78. public static IEnumerable<TDestination> Map<TSource, TDestination>(this ICollection<TSource> source)
  79. {
  80. foreach (TSource s in source)
  81. {
  82. yield return s.Map<TSource, TDestination>();
  83. }
  84. }
  85. }
  86. }