前言

我们在编程过程中,经常需要将一个对象转成另一个对象(一般称为对象映射)。

比如我们有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;}
}

两个类都拥有属性 istr

当我们需要将 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个属性相近的对象相互转换的更多相关文章

  1. Powermockito 针对方法中new 对象的模拟,以及属性中new 对象的模拟

    PowerMocker 是一个功能逆天的mock 工具. 一,Powermockito 针对方法中new 对象的模拟 // 如何才能mock掉 WeChatConfigUtil 这个类,让 weCha ...

  2. Python与数据库[2] -> 关系对象映射/ORM[2] -> 建立声明层表对象的两种方式

    建立声明层表对象的两种方式 在对表对象进行建立的时候,通常有两种方式可以完成,以下是两种方式的建立过程对比 首先导入需要的模块,获取一个声明层 from sqlalchemy.sql.schema i ...

  3. PHP设计模式笔记六:数据对象映射模式 -- Rango韩老师 http://www.imooc.com/learn/236

    数据对象映射模式 1.数据对象映射模式,是将对象和数据存储映射起来,对一个对象的操作会映射为对数据存储的操作 2.在代码中实现数据对象映射模式,我们将实现一个ORM类,将复杂的SQL语句映射成对象属性 ...

  4. 处理Selection对象和Range对象——Word VBA中重要的两个对象

    处理Selection对象和Range对象——Word VBA中重要的两个对象 Word 开发人员参考Selection 对象代表窗口或窗格中的当前所选内容.所选内容代表文档中选定(或突出显示)的区域 ...

  5. Android 学习笔记之AndBase框架学习(五) 数据库ORM..注解,数据库对象映射...

    PS:好久没写博客了... 学习内容: 1.DAO介绍,通用DAO的简单调度过程.. 2.数据库映射关系... 3.使用泛型+反射+注解封装通用DAO.. 4.使用AndBase框架实现对DAO的调用 ...

  6. 关于对象映射(Dto->model) 思路的一些想法

    最近粗浅的学习了下AutoMapper 这个做对象映射的第三方工具,觉得非常方便使用,所以简单的总结了一下我能想到的简单的对象映射的方式. 占时先不考虑源对象成员到目标对象成员的指定映射(即成员名不一 ...

  7. C# 高性能对象映射(表达式树实现)

    前言 上篇简单实现了对象映射,针对数组,集合,嵌套类并没有给出实现,这一篇继续完善细节. 开源对象映射类库映射分析 1.AutoMapper 实现原理:主要通过表达式树Api 实现对象映射 优点: . ...

  8. ASP.NET CORE 中使用AutoMapper进行对象映射

    ASP.NET CORE 中使用AutoMapper进行对象映射 1.什么是AutoMapper? AutoMapper是基于对象到对象约定的映射工具,常用于(但并不仅限制于)把复杂的对象模型转为DT ...

  9. Mybaits的中的对象映射(包含仅有基本数据类型的属性的和对象类型的属性的)

    转:https://blog.csdn.net/cjt20100/article/details/46547617. 1 constructor – 用来将结果反射给一个实例化好的类的构造器    a ...

随机推荐

  1. YAOI Round #7 题解

    前言 比赛链接: Div.1 : http://47.110.12.131:9016/contest/16 Div.2 : http://47.110.12.131:9016/contest/15 D ...

  2. jconsole和jstack

    1.jconsole jconsole是jdk自带的一个可视化的jvm监控工具,可以监控本地的jvm,也可以监控远程jvm 打开本地jdk安装目录下的bin目录下的jconsole.exe 2.jst ...

  3. 常见内部排序算法对比分析及C++ 实现代码

    内部排序是指在排序期间数据元素全部存放在内存的排序.外部排序是指在排序期间全部元素的个数过多,不能同时存放在内存,必须根据排序过程的要求,不断在内存和外存之间移动的排序.本次主要介绍常见的内部排序算法 ...

  4. 团队开发day02

    进行android的UI界面设计,设计圆角输入框和圆形按钮, 以及点击的水滴效果 遇到问题,新建的drawable布局没有达到预期的效果,圆形按钮的 背景想设置为图片,但是发现会遮盖住水滴效果,改用新 ...

  5. js学习-es6实现枚举

    最近大部分时间再写dart,突然用到js,发现js不能直接声明一个枚举.搜索发现还是有实现的方式,于是总结一下. 目录 枚举特点 Object.freeze() Symbol 实现 体现不可更改 体现 ...

  6. 【LeetCode】59.螺旋矩阵II

    59.螺旋矩阵II 知识点:数组: 题目描述 给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix . 示例 输入:n = 3 ...

  7. Unittest方法 -- 以test开头实例

    此篇是以下面的test作为实战的 : Unittest方法 -- 项目实现自动发送邮件 1.test_01 import unittestfrom selenium import webdriverc ...

  8. Album++:分布式事务专辑-基础概念

    (一)基础概念:↓ ↓ ↓ 1.1)什么是事务 什么是事务?举个生活中的例子:你去小卖铺买东西,"一手交钱,一手交货"就是一个事务的例子,交钱和交货必 须全部成功, 事务才算成功, ...

  9. 微信小程序云开发-云存储-下载并打开文件文件(word/excel/ppt/pdf)

    一.wxml文件 1.写文本框,用来获取文件链接. 2.按钮,点击下载文件 <!-- 下载文件(word/excel/ppt/pdf等) --> <view class=" ...

  10. odoo14--odoo前端框架owl【odoo web library】

    原文链接:https://www.alanhou.org/odoo-14-owl-todolist/ 1.组件树 Root         /   \        A     B       / \ ...