前言
在日常的开发中,作为一个小白的我曾遇到过一个问题,希望实现将一个对象转换为另一个对象,可奈何所学甚少不知如何下手,那么就出现了以下的代码:
entity1.Name = entity2.Name;
entity1.Age = entity2.Age;
...
...
就好比以上代码,依次赋值,如果这是一次操作那倒无所谓,可是如果说在一个项目中全部用这种方式,那就显得有点可笑了。那么如何实现一个自动关系映射的功能呢,那就是使用反射。当然我们可以选择加载使用现有的第三方库函数。
开始
下面将利用反射来实现自动关系映射,实现效果是把一个实体类转换为另一个实例类,两个实体类中相同属性名的值将会被转换,源实体或者目标实体中多余的属性将被忽略。
实现测试
定义两个实体对象
StudentAO stuAO = new StudentAO();
StudentDO stuDO = new StudentDO() { Age=18, Name = "lai9sky", Price=45};
遍历目标属性获取属性值
foreach (var pi in typeof(StudentAO).GetProperties())
{
}
通过当前遍历的属性名称,在源对象中获取与目标属性相同的属性的属性值
object temp = typeof(StudentDO).GetProperty(pi.Name).GetValue(stuDO, null);
将该值设置给目标属性
pi.SetValue(stuAO, pro, null);
整合代码
利用泛型实现一个泛型函数,实现接受任意的两个对象的映射。
/// <summary>
/// 把实体arg1 转换为实体arg2
/// </summary>
/// <typeparam name="T1"></typeparam>
/// <typeparam name="T2"></typeparam>
/// <param name="arg1"></param>
/// <param name="arg2"></param>
private bool AutoMap<T1,T2>(T1 arg1,T2 arg2)
{
bool res = false;
try
{
foreach (var pi in typeof(T2).GetProperties())
{
PropertyInfo prop = typeof(T1).GetProperty(pi.Name);
//如果目标实体中的属性在源实体类中不存在,则忽略该属性转换
if (prop != null)
{
object value = prop.GetValue(arg1, null);
pi.SetValue(arg2, value, null);
}
}
res = true;
}
catch (Exception err)
{
}
return res;
}
进阶
以上对象关系的映射存在一些缺陷,就是只能映射具有相同属性名称的两个对象,那么怎么可以映射两个对象之间不同属性名称的属性呢?
思路
结合.NET提供的另一个功能—特性,在定义实体类时使用特性指定需要映射的目标对象和源对象的属性名称,然后在代码运行时动态检查该特性的特性值,然后通过特性值获取源对象的属性值或设置目标对象的属性值。对于自定义特性的实现参考另一篇文章,这里不做太多的说明。
实现
这里就不做实现,自己可以尝试着去实现,相信自己一定可以。如果在实现的过程中遇到了问题可以联系我,和我一起讨论。
后记
有来有往,感谢您的阅读,如有不足还请原谅,若可不吝指教小厮将感激不尽。