ExpressionGenericMapper.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq.Expressions;
  4. namespace Masuit.Tools.Core
  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. if (source == null)
  42. {
  43. return default(TDestination);
  44. }
  45. return ((Func<TSource, TDestination>)func)(source); //拼装是一次性的
  46. }
  47. /// <summary>
  48. /// 集合映射
  49. /// </summary>
  50. /// <typeparam name="TSource"></typeparam>
  51. /// <typeparam name="TDestination"></typeparam>
  52. /// <param name="source"></param>
  53. /// <returns></returns>
  54. public static IEnumerable<TDestination> Map<TSource, TDestination>(this IEnumerable<TSource> source)
  55. {
  56. foreach (TSource s in source)
  57. {
  58. yield return s.Map<TSource, TDestination>();
  59. }
  60. }
  61. /// <summary>
  62. /// 集合映射
  63. /// </summary>
  64. /// <typeparam name="TSource"></typeparam>
  65. /// <typeparam name="TDestination"></typeparam>
  66. /// <param name="source"></param>
  67. /// <returns></returns>
  68. public static IEnumerable<TDestination> Map<TSource, TDestination>(this IList<TSource> source)
  69. {
  70. foreach (TSource s in source)
  71. {
  72. yield return s.Map<TSource, TDestination>();
  73. }
  74. }
  75. /// <summary>
  76. /// 集合映射
  77. /// </summary>
  78. /// <typeparam name="TSource"></typeparam>
  79. /// <typeparam name="TDestination"></typeparam>
  80. /// <param name="source"></param>
  81. /// <returns></returns>
  82. public static IEnumerable<TDestination> Map<TSource, TDestination>(this ICollection<TSource> source)
  83. {
  84. foreach (TSource s in source)
  85. {
  86. yield return s.Map<TSource, TDestination>();
  87. }
  88. }
  89. }
  90. }