C# 对象类型映射转换方法总结,表达式目录树实现高效转换

       开发过程中经常会遇到对象类型之间的转换映射,例如Model和ViewModel之间的映射绑定,下面总结几种常见的转换方式。事先准备两个类:
CheckFileCheckFileModel


 	public class CheckFile
    {
        public string Id { get; set; }
        public string FileTitle { get; set; }
        public string Author { get; set; }
        public DateTime? CreatTime;
    }
    
    public class CheckFileModel
    {
        public string Id { get; set; }
        public string FileTitle { get; set; }
        public string Author { get; set; }
        public DateTime? CreatTime;
        public string Source { get; set; }
    }

1. 强类型赋值绑定

    
    CheckFile checkFile = new CheckFile
    {
        Id = "123",
        FileTitle = "对象类型转换映射",
        Author = "张三",
        CreatTime = DateTime.Now
    };

	CheckFileModel fileModel = new CheckFileModel
    {
        Id = checkFile.Id,
        FileTitle = checkFile.FileTitle,
        Author = checkFile.Author,
        CreatTime = checkFile.CreatTime
    };
    

2. 泛型+反射


	  /// <summary>
      /// 泛型+反射
      /// </summary>
      /// <typeparam name="TOut"></typeparam>
      /// <typeparam name="TIn"></typeparam>
      /// <param name="objIn"></param>
      /// <returns></returns>
      public static TOut TypeConvert<TOut, TIn>(TIn objIn)
      {
          Type tOut = typeof(TOut);
          Type tIn = typeof(TIn);
          TOut outModel = Activator.CreateInstance<TOut>();

          // 属性赋值
          foreach (var prop in tOut.GetProperties())
          {
              var propInfo = tIn.GetProperty(prop.Name);
              if (propInfo != null)
              {
                  var inValue = propInfo.GetValue(objIn);
                  prop.SetValue(outModel, inValue);
              }
          }

          // 字段赋值
          foreach (var field in tOut.GetFields())
          {
              var fieldInfo = tIn.GetField(field.Name);
              if (fieldInfo != null)
              {
                  var inValue = fieldInfo.GetValue(objIn);
                  field.SetValue(outModel, inValue);
              }
          }
          return outModel;
      }
    

3. Json序列化转换


      /// <summary>
      /// Json序列化转换
      /// </summary>
      /// <typeparam name="TOut"></typeparam>
      /// <typeparam name="TIn"></typeparam>
      /// <param name="objIn"></param>
      /// <returns></returns>
      public static TOut SerializeConvert<TOut, TIn>(TIn objIn)
      {
          string inString = JsonConvert.SerializeObject(objIn);
          TOut outModel = JsonConvert.DeserializeObject<TOut>(inString);
          return outModel;
      }
      

4. AutoMapper序列化转换


      /// <summary>
      /// AutoMapper序列化转换
      /// </summary>
      /// <typeparam name="TOut"></typeparam>
      /// <typeparam name="TIn"></typeparam>
      /// <param name="objIn"></param>
      /// <returns></returns>
      public static TOut AutoMapperConvert<TOut, TIn>(TIn objIn)
      {
          // 初始化
          Mapper.Initialize(n => n.CreateMap<TIn, TOut>());

          TOut outModel = Mapper.Map<TIn, TOut>(objIn);
          return outModel;
      }
        

5. Expression表达式目录树转换


      /// <summary>
      /// Expression表达式目录树转换
      /// </summary>
      /// <typeparam name="TOut"></typeparam>
      /// <typeparam name="TIn"></typeparam>
      /// <param name="objIn"></param>
      /// <returns></returns>
      public static TOut ExpressionConvert<TOut, TIn>(TIn objIn)
      {
          ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn), "p");
          List<MemberBinding> memberBindingList = new List<MemberBinding>();

          // 绑定属性
          PropertyInfo[] outPropertyInfos = typeof(TOut).GetProperties();
          foreach (var prop in outPropertyInfos)
          {
              PropertyInfo inPropertyInfo = typeof(TIn).GetProperty(prop.Name);
              if (inPropertyInfo != null)
              {
                  MemberExpression property = Expression.Property(parameterExpression, inPropertyInfo);
                  MemberBinding memberBinding = Expression.Bind(prop, property);
                  memberBindingList.Add(memberBinding);
              }
          }

          // 绑定字段
          FieldInfo[] outFieldInfos = typeof(TOut).GetFields();
          foreach (var field in outFieldInfos)
          {
              FieldInfo inFieldInfo = typeof(TIn).GetField(field.Name);
              if (inFieldInfo != null)
              {
                  MemberExpression fieldInfo = Expression.Field(parameterExpression, inFieldInfo);
                  MemberBinding memberBinding = Expression.Bind(field, fieldInfo);
                  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<TIn, TOut> func = lambda.Compile();
          return func.Invoke(objIn);
      }
	  
	  //----------------------------------------------------------
	  // 等价于构造一个下面的表达式
      Expression<Func<CheckFile, CheckFileModel>> lambda = p => new CheckFileModel
      {
          Id = p.Id,
          FileTitle = p.FileTitle,
          Author = p.Author,
          CreatTime = p.CreatTime
      };
      lambda.Compile().Invoke(checkFile);

       

表达式目录树

在这里插入图片描述
每个矩形框为一个节点(表达式类型),节点有多种类型,对于而这个 a*b+2 的几个节点:

  • a,b是参数,类型为ParameterExpression
  • +,*,为二元运符,类型为BinaryExpression
  • 2为常量,类型为ConstantExpression

	Expression<Func<int, int, int>> exp1 = (a, b) => a * b+2;

	//两个参数
	ParameterExpression a = Expression.Parameter(typeof(int), "a");
	ParameterExpression b = Expression.Parameter(typeof(int), "b"); 
	
	//求积
	BinaryExpression Multi=Expression.Multiply(a,b); 
	
	//常量
	ConstantExpression x2 = Expression.Constant(2); 
	
	//求和
	BinaryExpression Add = Expression.Add(Multi, x2); 
	
	//创建一个表示lambda表达式的对象
	LambdaExpression lexp = Expression.Lambda<Func<int, int, int>>(Add, a, b); 

	//查看表达式
	Console.WriteLine(lexp.ToString());
	
	//简单使用
	Expression<Func<int, int, int>> lexp = Expression.Lambda<Func<int, int, int>>(Add, a, b);
	Func<int, int, int> fun = lexp.Compile();
	Console.WriteLine(fun(3,5));
	

END

猜你喜欢

转载自blog.csdn.net/qq_31176861/article/details/86551996