基于IL的C#任意类型自动深拷贝与深比较工具
2021/11/19 1:10:24
本文主要是介绍基于IL的C#任意类型自动深拷贝与深比较工具,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
一、前言
本文的动机需求在于对任意一个类型MyClass,可以在不需要书写任何额外代码的同时自动进行深拷贝以及深比较,并且需要保证一定的性能。之前的方案是两年前使用Python正则自动生成代码,性能当然是最高的,但是使用起来比较麻烦:使用Python自动生成代码。最近学习了C#的IL以后,发现了一种不错的解决方案。
二、IL介绍
IL是C#编译后生成的一种中间代码,之后才会被JIT解释生成对应的机器码进行执行。同时,C#提供了手动书写IL,并转换为方法的API,具体使用方法不做过多赘述,可以参见之前的一篇文章,文中提供了利用IL Emit进行动态创建一个类型的方法:通过IL Emit来创建类型。
简而言之,利用IL可以书写任意类型的C#代码(因为C#本来就被编译生成IL),然后转化成运行时function,这样的性能基本相当于手写C#代码的速度。
三、思路
需求是对一个类型生成对应的深拷贝代码,然后利用IL进行书写并生成,那么怎么递归获取内部所有成员变量呢,答案是利用反射。当然,反射显然比较慢,于是我们利用空间换时间的思路,将对应类型所生成的深拷贝方法保存在一张表里,下次直接使用即可。
于是整个流程如下:传入一个类型,检查表内是否已经存在对应深拷贝方法,如果有则直接返回;如果不存在,则利用反射递归查找所有的成员变量,之后利用IL生成相应的方法,存入表中并返回。(显然,第一次生成的时候会有一定开销)
四、应用
思路其实比较简单,但是实际上细节和坑还是很多的:
1. 需要熟悉OpCodes码,这部分可以查阅资料进行了解。
2. 需要知道各种C#代码怎么转换成IL,这部分可以通过将ildasm将C#生成的dll转化成IL进行查看,可百度了解使用方式。
3. 需要验证生成的IL代码对应怎样的C#代码时,可以利用API将书写的IL代码生成dll,然后使用Reflector进行转化成C#代码,有时候不知道书写的IL代码为何不对时,这个方法非常好用。不过Reflector是收费的,据说ILSpy也可以使用,但是笔者没有用过,以后有机会试试。
4. 书写IL代码是一件困难的事,因为其语法类似于汇编,所以需要事先构建一个简单的框架来书写面向过程的代码,笔者提供的框架中,利用闭包简单的封装了方便使用的for和if功能,不然用汇编写这些确实有点繁琐。
5. Debug是一件困难的事。可以在每个OpCodes语句后面加Log,来观察生成的语句,并且书写同样的C#代码使用ildasm生成IL之后进行比对;或者使用第三点来比对C#代码。
五、工程
笔者提供一个git作为参考,可直接使用。https://github.com/523810185/TypeCmpAndCloneGenerator
这篇关于基于IL的C#任意类型自动深拷贝与深比较工具的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2022-03-01沐雪多租宝商城源码从.NetCore3.1升级到.Net6的步骤
- 2024-11-18微软研究:RAG系统的四个层次提升理解与回答能力
- 2024-11-15C#中怎么从PEM格式的证书中提取公钥?-icode9专业技术文章分享
- 2024-11-14云架构设计——如何用diagrams.net绘制专业的AWS架构图?
- 2024-05-08首个适配Visual Studio平台的国产智能编程助手CodeGeeX正式上线!C#程序员必备效率神器!
- 2024-03-30C#设计模式之十六迭代器模式(Iterator Pattern)【行为型】
- 2024-03-29c# datetime tryparse
- 2024-02-21list find index c#
- 2024-01-24convert toint32 c#
- 2024-01-24Advanced .Net Debugging 1:你必须知道的调试工具