.NET core高性能对象转换示例代码
程序员文章站
2022-03-09 21:44:45
前言
net core(开放源代码,跨平台,x-copy可部署等)有许多令人兴奋的方面,其中最值得称赞的就是其性能了。关于对象转换已经有不少*(automapper,t...
前言
net core(开放源代码,跨平台,x-copy可部署等)有许多令人兴奋的方面,其中最值得称赞的就是其性能了。关于对象转换已经有不少*(automapper,tinymapper) .出于项目需要,手动造一个简单*。下面话不多说了,来一起看看详细的介绍吧。
示例代码
g>1.采用静态泛型类缓存,避免了拆箱装箱操作。
2.对于转换对象中有,字段名一样但是类型不一样的类时仍可以用
public static class mapper<tsource, ttarget> where tsource : class where ttarget : class { public readonly static func<tsource, ttarget> map; static mapper() { if (map == null) map = getmap(); } private static func<tsource, ttarget> getmap() { var sourcetype = typeof(tsource); var targettype = typeof(ttarget); var parameterexpression = expression.parameter(sourcetype, "p"); var memberinitexpression = getexpression(parameterexpression, sourcetype, targettype); var lambda = expression.lambda<func<tsource, ttarget>>(memberinitexpression, parameterexpression); return lambda.compile(); } /// <summary> /// 根据转换源和目标获取表达式树 /// </summary> /// <param name="parameterexpression">表达式参数p</param> /// <param name="sourcetype">转换源类型</param> /// <param name="targettype">转换目标类型</param> /// <returns></returns> private static memberinitexpression getexpression(expression parameterexpression, type sourcetype, type targettype) { var memberbindings = new list<memberbinding>(); foreach (var targetitem in targettype.getproperties().where(x => x.propertytype.ispublic && x.canwrite)) { var sourceitem = sourcetype.getproperty(targetitem.name); //判断实体的读写权限 if (sourceitem == null || !sourceitem.canread || sourceitem.propertytype.isnotpublic) continue; //标注notmapped特性的属性忽略转换 if (sourceitem.getcustomattribute<notmappedattribute>() != null) continue; var propertyexpression = expression.property(parameterexpression, sourceitem); //判断都是class 且类型不相同时 if (targetitem.propertytype.isclass && sourceitem.propertytype.isclass && targetitem.propertytype != sourceitem.propertytype) { if (targetitem.propertytype != targettype)//防止出现自己引用自己无限递归 { var memberinit = getexpression(propertyexpression, sourceitem.propertytype, targetitem.propertytype); memberbindings.add(expression.bind(targetitem, memberinit)); continue; } } if (targetitem.propertytype != sourceitem.propertytype) continue; memberbindings.add(expression.bind(targetitem, propertyexpression)); } return expression.memberinit(expression.new(targettype), memberbindings); } }
3.调用方法如下
(1)构造样例类
public class a { public int id { get; set; } public string name { get; set; } public c user { get; set; } /// <summary> /// 标注为notmapped特性时,不转换赋值 /// </summary> [system.componentmodel.dataannotations.schema.notmapped] public d usera { get; set; } } public class b { public int id { get; set; } public string name { get; set; } public d user { get; set; }<br data-filtered="filtered"> public d usera { get; set; } } public class c { public int id { get; set; } public string name { get; set; } } public class d { public int id { get; set; } public string name { get; set; } }
(2) 调用
var a = new a { id = 1, name = "张三", user = new c { id = 1, name = "李四" } };<br> b b = mapper<a, b>.map(a);//得到转换结果
4.性能测试
var length = 10000000; var lista = new list<a>(); for (int i = 0; i < length; i++) { lista.add(new a { id = i, name = "张三", user = new c { id = i, name = "李四" } }); } var sw = stopwatch.startnew(); for (int i = 0; i < length; i++) { var item = lista[i]; var b = new b { id = item.id, name = item.name, user = new d { id = i, name = "李四", } }; } sw.stop(); console.writeline($"原生的时间:{sw.elapsedmilliseconds}ms"); //表达式 mapper<a, b>.map(lista[0]);//预先编译缓存 sw.restart(); for (int i = 0; i < length; i++) { mapper<a, b>.map(lista[i]); } sw.stop(); console.writeline($"表达式的时间:{sw.elapsedmilliseconds}ms"); //automapper automapper.mapper.initialize(cfg => cfg.createmap<a, b>()); sw.restart(); for (int i = 0; i < length; i++) { var b = automapper.mapper.map<b>(lista[i]); } sw.stop(); console.writeline($"automapper时间:{sw.elapsedmilliseconds}ms"); //tinymapper tinymapper.bind<a, b>(); sw.restart(); for (int i = 0; i < length; i++) { var b = tinymapper.map<b>(lista[i]); } sw.stop(); console.writeline($"tinymapper时间:{sw.elapsedmilliseconds}ms"); console.readline();
5. 1000万数据不带子类集结果
6. 1000万数据带子类集结果
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。