今天来给大家讲讲如何用C# 快速高效复制对象,干货多多,不要错过哦!
废话不多说直接上干货。
1、需求
在代码中经常会遇到需要把对象A转换成对象B,二者属性一致(不一致可以增加映射规则)。
2、解决方案
2.1、硬编码
直接硬编码写死转换,速度肯定最快,但是完全没有通用性,只能处理单一情况。
调用一百万次耗时:26毫秒
2.2、反射
反射应该是很多人用过的方法,就是封装一个方法,反射获取属性值,然后设置给目标对象。
调用一百万次耗时:2464毫秒
2.3、序列化反序列化
序列化的方式有很多种,有二进制、xml、json等等,今天我们就用Newtonsoft的json进行测试,序列化后再反序列化,调用一百万次耗时:2984毫秒
从这可以看出序列化和反射效率差别不大。
2.4、表达式树缓存
既然上面用了反射性能都不理想,反而是硬编码效率最高,那我们不如想想办法通过硬编码的方式来转换,但是这个硬编码是通过别的方式生成了,这就是表达式树。
调用一百万次耗时:564毫秒
2.5、表达式树+泛型变量
上面使用了静态字典来保存委托,100w次的调用大部分时间都用来字典查找和类型转换了,下面用泛型类静态变量的封闭特性进行优化:
调用一百万次耗时:107毫秒
2.5、automapper
还有种方式是使用automapper工具,原理也是生成硬编码,只不过是通过emit完成的,调用一百万次是338毫秒
4、总结
从以上的测试和分析可以很容易得出,用表达式树+泛型是最优的解决方案,比传统的序列化反序列化和反射更加优秀,甚至还能超越一些成熟工具的性能。同时感慨一下,精益求精,进无止境。