C# 通过反射实现对象映射:将2个属性相近的对象相互转换
前言
我们在编程过程中,经常需要将一个对象转成另一个对象(一般称为对象映射)。
比如我们有2个类:
//第1个类 CLS1
class CLS1
{
public int i {get; set;}
public string str {get; set;}
}
//第2个类 CLS2
class CLS2
{
public int i {get; set;}
public string str {get; set;}
}
两个类都拥有属性 i
和 str
。
当我们需要将 CLS1 的实例对象转化为 CLS2 的实例对象时,正常会这样操作:
CLS1 obj1 = new CLS1(){i = 1, str = "ss"};
CLS2 obj2 = new CLS2();
//将 obj1 映射为 obj2
obj2.i = obj1.i; //obj2.i = 1;
obj2.str = obj1.str; //obj2.str = "ss";
如果属性多了,写起来会很繁琐,希望可以通过一个方法自动帮我们解决,比如这样:
//将 CLS1 的对象映射为 CLS2 的对象
obj2 = Mapper.T1MapToT2<CLS1, CLS2>(obj1); //obj2.i = 1; obj2.str = "ss";
实现
以下是实现代码:
public class Mapper
{
/// <summary>
/// 通过反射,将 T1 映射为 T2
/// </summary>
/// <typeparam name="T1"></typeparam>
/// <typeparam name="T2"></typeparam>
/// <param name="t1"></param>
/// <returns></returns>
public static T2 T1MapToT2<T1, T2>(T1 t1)
where T1 : class
where T2 : class //, new()
{
T2 t2 = Activator.CreateInstance<T2>(); //T2 t2 = new T2(); //后面这种写法,要在 where 中添加 new()
if (t1 == null)
{
return t2;
}
var p1 = t1.GetType().GetProperties();
var p2 = typeof(T2).GetProperties();
for (int i = 0; i < p1.Length; i++)
{
//条件:1、属性名相同;2、t2属性可写;3、属性可读性一致;4、数据类型相近(相同,或者接近。接近如:int 和 int?)
var p = p2.Where(t => t.Name == p1[i].Name && t.CanWrite && t.CanRead == p1[i].CanRead).FirstOrDefault();
if (p == null)
continue;
var v = p1[i].GetValue(t1);
if (v == null)
continue;
try { p.SetValue(t2, v); } //难判定数据类型,暂时这样处理
catch
{
try { p.SetValue(t2, Convert.ChangeType(v, p.PropertyType)); } //int? -> object -> int? 会抛错
catch { }
}
}
return t2;
}
//这种写法和上面的写法没啥差别
public static T2 T1MapToT2_2<T1, T2>(T1 t1)
where T1 : class
where T2 : class //, new()
{
T2 t2 = Activator.CreateInstance<T2>(); //T2 t2 = new T2(); //后面这种写法,要在 where 中添加 new()
var p1 = t1.GetType().GetProperties();
var p2 = typeof(T2);
for (int i = 0; i < p1.Length; i++)
{
//条件:1、属性名相同;2、t2属性可写;3、属性可读性一致;4、数据类型相近(相同,或者接近。接近如:int 和 int?)
var p = p2.GetProperty(p1[i].Name);
if (p == null || !p.CanWrite || p.CanRead != p1[i].CanRead)
continue;
var v = p1[i].GetValue(t1);
if (v == null)
continue;
try { p.SetValue(t2, Convert.ChangeType(v, p.PropertyType)); }
catch { }
}
return t2;
}
}
C# 通过反射实现对象映射:将2个属性相近的对象相互转换的更多相关文章
- Powermockito 针对方法中new 对象的模拟,以及属性中new 对象的模拟
PowerMocker 是一个功能逆天的mock 工具. 一,Powermockito 针对方法中new 对象的模拟 // 如何才能mock掉 WeChatConfigUtil 这个类,让 weCha ...
- Python与数据库[2] -> 关系对象映射/ORM[2] -> 建立声明层表对象的两种方式
建立声明层表对象的两种方式 在对表对象进行建立的时候,通常有两种方式可以完成,以下是两种方式的建立过程对比 首先导入需要的模块,获取一个声明层 from sqlalchemy.sql.schema i ...
- PHP设计模式笔记六:数据对象映射模式 -- Rango韩老师 http://www.imooc.com/learn/236
数据对象映射模式 1.数据对象映射模式,是将对象和数据存储映射起来,对一个对象的操作会映射为对数据存储的操作 2.在代码中实现数据对象映射模式,我们将实现一个ORM类,将复杂的SQL语句映射成对象属性 ...
- 处理Selection对象和Range对象——Word VBA中重要的两个对象
处理Selection对象和Range对象——Word VBA中重要的两个对象 Word 开发人员参考Selection 对象代表窗口或窗格中的当前所选内容.所选内容代表文档中选定(或突出显示)的区域 ...
- Android 学习笔记之AndBase框架学习(五) 数据库ORM..注解,数据库对象映射...
PS:好久没写博客了... 学习内容: 1.DAO介绍,通用DAO的简单调度过程.. 2.数据库映射关系... 3.使用泛型+反射+注解封装通用DAO.. 4.使用AndBase框架实现对DAO的调用 ...
- 关于对象映射(Dto->model) 思路的一些想法
最近粗浅的学习了下AutoMapper 这个做对象映射的第三方工具,觉得非常方便使用,所以简单的总结了一下我能想到的简单的对象映射的方式. 占时先不考虑源对象成员到目标对象成员的指定映射(即成员名不一 ...
- C# 高性能对象映射(表达式树实现)
前言 上篇简单实现了对象映射,针对数组,集合,嵌套类并没有给出实现,这一篇继续完善细节. 开源对象映射类库映射分析 1.AutoMapper 实现原理:主要通过表达式树Api 实现对象映射 优点: . ...
- ASP.NET CORE 中使用AutoMapper进行对象映射
ASP.NET CORE 中使用AutoMapper进行对象映射 1.什么是AutoMapper? AutoMapper是基于对象到对象约定的映射工具,常用于(但并不仅限制于)把复杂的对象模型转为DT ...
- Mybaits的中的对象映射(包含仅有基本数据类型的属性的和对象类型的属性的)
转:https://blog.csdn.net/cjt20100/article/details/46547617. 1 constructor – 用来将结果反射给一个实例化好的类的构造器 a ...
随机推荐
- Linux | 管首命令符号
简介 管道的意思,在我们日常生活中,意思就是运输一个东西,到下一个地方,所以说 管道命令符 的使用也是差不多的,也是运送一段数据到下一个地方,格式:命令A | 命令B | 命令C .... 所以说,管 ...
- 「CF526F」 Pudding Monsters
CF526F Pudding Monsters 传送门 模型转换:对于一个 \(n\times n\) 的棋盘,若每行每列仅有一个棋子,令 \(a_x=y\),则 \(a\) 为一个排列. 转换成排列 ...
- CSP2020游记
初赛 这次考试完全没准备好啊-- Day0 (10.10) 本来打算看看初赛的内容 然后因为各种原因咕了-- 就做了一下洛谷的模拟卷 结果 \(40 \text{min}\) 得 \(80 \text ...
- Spring BeanFactory和现实工厂的对比
本文不分析Spring的源码流程,只是介绍一些基础的概念,在阅读源码之前,我们应该首先明确研究的对象是什么,才能有的放矢. Spring作为BeanFactory, 和现实工厂有着许多类似之处. 需要 ...
- C语言:编译具体过程及隐藏
对于平常应用程序的开发,很少有人会关注编译和链接的过程,因为我们使用的工具一般都是流行的集成开发环境(IDE),比如 Visual Studio.Dev C++.C-Free 等.这些功能强大的 ID ...
- yoyogo v1.7.6 增强程序优雅退出和K8s Readiness检查
YoyoGo (Go语言框架)一个简单.轻量.快速.基于依赖注入的微服务框架( web .grpc ),支持Nacos/Consoul/Etcd/Eureka/k8s /Apollo等 . 本次更新增 ...
- [刘阳Java]_Spring入门_第1讲
Spring框架在企业中的使用非常多,优势明显.所以学好Spring框架肯定不言而喻.今天我们给大家介绍Spring的入门 1. 对于初学者来说我们要学习Spring框架中的哪些技术,这个有必要了解一 ...
- 详解API Gateway流控实现,揭开ROMA平台高性能秒级流控的技术细节
摘要:ROMA平台的核心系统ROMA Connect源自华为流程IT的集成平台,在华为内部有超过15年的企业业务集成经验. 本文分享自华为云社区<ROMA集成关键技术(1)-API流控技术详解& ...
- 微信小程序云开发-云存储的应用-识别通用印刷体
一.准备工作 1.创建云函数identify 2.云函数identify中index.js代码 1 // 云函数入口文件 2 const cloud = require('wx-server-sdk' ...
- C++第四十一篇 -- 安装成功的第一个驱动文件
参考链接:https://blog.csdn.net/LEON1741/article/details/87291839 一.新建工程 二.写一个Driver.c #include <ntddk ...