转载请注明出处:http://blog.csdn.net/water_0815/article/details/53240037
本文同步发表于我的微信公众号和简书社区。
微信公众号:惜福 / xifu_forever(扫一扫文章底部的二维码即可关注)
简书作者号:一度罪恶
这是我的第一篇技术性原创文章,平时分享的文章离代码都有点远,一时间不知道怎么写了,真是“万事开头难”,不管怎么样,先写了再说。就先分享点简单的东西吧,主要偏向于个人总结,如果对大家有所帮助,再好不过。
1.业务场景
也许大家都遇到过这种纠结,即如何从一个数据模型(姑且叫Model1)转换成另一个数据模型(Model2)?Model1和Model2有部分相同的属性、类型,我们希望将Model1属性的值赋于Model2相对应的属性,比如,将API接口数据模型转为数据库的数据模型。一般情况下,API接口接收到的数据包含了一些业务逻辑的字段,并不都需要保存到数据库。
当这种情况比较少时,我们可以在数据模型内部实现一个转换的方法,专门处理对应的API接口数据模型与数据库数据模型之间的转换映射。而这种需求比较多,Model又不确定的情况下,要是有一个能够处理并兼容各种Model之间的数据转换就好了。很高兴的是,一般的编程语言都支持泛型,今天我们就以C#为例,来实现这样一个方法。
2.技术实现
首先,创建两个测试的实体类(Model),UserInfoOrigin和UserInfoResult(此处也包含了泛型属性),如下所示:
public class UserInfoOrigin<T>
{
public int UserId { set; get; }
public string UserName { set; get; }
public string Password { set; get; }
public T UnknownType { set; get; }
public EnumList.Sex Gender { set; get; }
}
public class UserInfoResult<T>
{
public int UserId { set; get; }
public string UserName { set; get; }
//public string Password { set; get; }
public T UnknownType { set; get; }
public EnumList.Sex Gender { set; get; }
}
接着,再创建一个实体类TestModel,用来给UserInfoOrigin和UserInfoResult的泛型属性T指定类型。当然,你也可以指定其他基础数据结构的类型,比如Int,String,List,DateTime等,这里我们测试最复杂的Class类型。
public class TestModel
{
public int TestId { set; get; }
public string TestName { set; get; }
}
接下来,我们就要实现一个通用的处理方法,称为ConvertModel,要求传入一个Model1,返回另一个Model2,出来时的Model2就自动赋上Model1相对应的属性值了。如下所示:
/// <summary>
/// Model 转换
/// </summary>
/// <typeparam name="TOrigin">转换前Model泛型</typeparam>
/// <typeparam name="TResult">转换后Model泛型</typeparam>
/// <param name="modelOrigin">转换前Model</param>
/// <returns></returns>
public static TResult ConvertModel<TOrigin, TResult>(TOrigin modelOrigin)
{
if (modelOrigin == null)
{
return default(TResult);
}
TResult modelRet = System.Activator.CreateInstance<TResult>();
PropertyInfo[] retModelPiInfos = typeof(TResult).GetProperties();
PropertyInfo[] oriModelPiInfos = typeof(TOrigin).GetProperties();
foreach (PropertyInfo piRet in retModelPiInfos)
{
String piName = piRet.Name;
PropertyInfo piOri = oriModelPiInfos.Where(p => p.Name == piName).FirstOrDefault();
if (piOri != null)
{
object valueOri = piOri.GetValue(modelOrigin);
object valueRet = null;
if (!string.IsNullOrEmpty(valueOri.ToString()))
{
valueRet = Convert.ChangeType(valueOri, piRet.PropertyType);
}
piRet.SetValue(modelRet, valueRet, null);
}
}
return modelRet;
}
最后,我们来测试一下是不是得到了我们想要的结果,测试代码如下所示:
static void Main(string[] args)
{
TestModel tm = new TestModel {
TestId = 0,
TestName = "TestNameValue"
};
UserInfoOrigin<TestModel> uOrigin = new UserInfoOrigin<TestModel>
{
UserId = 1,
UserName = "李海波",
Password = "abc123",
UnknownType = tm,
Gender = EnumList.Sex.男
};
UserInfoResult<TestModel> uResult = ModelTool.ConvertModel<UserInfoOrigin<TestModel>, UserInfoResult<TestModel>>(uOrigin);
if (uResult != null)
{
Console.WriteLine(uResult.ToString());
}
else
{
Console.WriteLine("null");
}
Console.ReadKey();
}
调试运行时,我们对UserInfoResult类型的uResult进行监视,得到以下结果,看来是对了:
今天的分享就到这。
关注我的微信公众号,专注于分享读书心得、编程艺术、随笔臆想等。微信扫一扫下方二维码即可关注:

1195

被折叠的 条评论
为什么被折叠?



