В больших данных / облачные вычисления / исследования искусственного интеллекта и эпоха развития популярности, рост агрессии Python и передние и задние концы Javascript, программисты и компания, кажется, все более и более популярные языки динамических приносят удобство и эффективность, даже на языке статического лучше, чем статические характеристики языка, проверка на наличии ошибок и другие аспекты. Для .NETer говоря, .NET как язык статической, мы должны не только заложить .NET базовые навыки, такие как базовый тип / грамматика / Основополагающий принцип / ошибка проверки знаний, но и глубокое понимание некоторых расширенных возможностей .NET, уменьшить нагрузку и улучшить качество коды для вашей работы.
Хорошо, мы начали общаться в .NET Emit сегодня.
Во-первых, что испускают?
Испустите значение выдается, означая производства, который представляет собой набор .NET библиотеки классов пространства имен System.Reflection.Emit, почти все версии .NET Framework поддержки (/ Mono / Netcore) Emit, могут быть реализованы в C # код генерируется код библиотеки
Во-вторых, природа Emit
Мы знаем, что .NET может быть изготовлен из различных языков, таких как VB, C ++ и т.д., конечно, подавляющее большинство программистов используют C # .NET язык разработки, какой язык будет истолковано соответствующий интерпретатор языка для языка и IL исполнение и роль библиотеки Emit написано на этих языках, чтобы генерировать IL языка, и в CLR (Common Language Runtime) для исполнения.
Давайте посмотрим на внешний вид языка IL, как:
(1) Во-первых, мы создаем, программу World Hello
Класс Program { статический аннулируются Main ( строка [] арг) { Console.WriteLine ( " Hello World! " ); } }
(2) программа компилируется в DLL файл, мы можем увидеть развитие каталога, созданного в папке бин
(3), глядя вниз, мы можем видеть, что DLL файл был создан, я использую netcore3 развития, это путь для бен / Debug / netcoreapp3.0
(4) В это время мы переставить себя на наш взгляд иль артефакт, ILDASM инструмент
Как найти этот инструмент? Откройте меню Пуск, найдите папку Визуальная студии и откройте Developer Командная строка, введите ILDASM Enter, чтобы открыть командную строку, я использую vs2019 презентации, против других версий операционных методов согласуются
(5) В DASM строке меню выберите Файл -> Открыть, выберите только что сгенерировали длл файл
(6) для просмотра генерации кода IL
С ILDASM вспомогательным, мы можем лучше понять язык, и как вы можете написать IL IL язык. Кроме того, Visual Studio есть много плагинов в поддержку просмотра кода иль, такие, как производится JetBrains ReSharper плагинов, если я чувствую, что путь больше проблем используя вышеупомянутую плагин иль просмотра кода
В-третьих, код IL оценил
在上一章节中,我们理解了Emit的本质其实就是用C#来编写IL代码,既然要编写IL代码,那么我们首先要理解IL代码是如何进行工作的,IL代码是如何完成C#当中的顺序/选择/循环结构的,是如何实现类的定义/字段的定义/属性的定义/方法的定义的。
IL代码是一种近似于指令式的代码语言,与汇编语言比较相近,所以习惯于写高级语言的.NETer来说比较难以理解
让我们来看看Hello,World程序的IL代码:
IL_0000: nop IL_0001: ldstr "Hello World!" IL_0006: call void [System.Console]System.Console::WriteLine(string) IL_000b: nop IL_000c: ret
我们可以把IL代码看成栈的运行
第一条指令,nop表示不做任何事情,表示代码不做任何事情
第二条指令,ldstr表示将字符串放入栈中,字符串的值为“Hello,World!”
第三条指令,call表示调用方法,参数为调用方法的方法信息,并把返回的结构压入栈中,使用的参数为之前已经入栈的“Hello World!”,以此类推,如果方法有n个参数,那么他就会调取栈中n个数据,并返回一个结果放回栈中
第四条指令,nop表示不做任何事情
第五条指令,ret表示将栈中顶部的数据返回,如果方法定义为void,则无返回值
关于Hello,world程序IL的理解就说到这里,更多的指令含义读者可以参考微软官方文档,笔者之后也会继续对Emit进行讲解和Emit的应用
四、用Emit类库编写IL代码
既然IL代码咱们理解的差不多了,咱们就开始尝试用C#来写IL代码了,有了IL代码的参考,咱们也可以依葫芦画瓢的把代码写出来了
(1) 引入Emit命名空间
using System.Reflection.Emit;
(2) 首先我们定义一个Main方法,入参无,返回类型void
//定义方法名,返回类型,输入类型 var method = new DynamicMethod("Main", null, Type.EmptyTypes);
(3) 生成IL代码
//生成IL代码 var ilGenerator = method.GetILGenerator(); ilGenerator.Emit(OpCodes.Nop); ilGenerator.Emit(OpCodes.Ldstr,"Hello World!"); ilGenerator.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })); //寻找Console的WriteLine方法 ilGenerator.Emit(OpCodes.Nop); ilGenerator.Emit(OpCodes.Ret);
(4) 创建委托并调用
//创建委托 var helloWorldMethod = method.CreateDelegate(typeof(Action)) as Action; helloWorldMethod.Invoke();
(5)运行,即输出Hello World!
五、小结
Emit的本质是使用高级语言生成IL代码,进而进行调用的的一组类库,依赖Emit我们可以实现用代码生成代码的操作,即编程语言的自举,可以有效弥补静态语言的灵活性的缺失。
Emit的性能非常好,除了第一次构建IL代码所需要时间外,之后只要将操作缓存在计算机内存中,速度与手写代码相差无几
有许多著名.NET类库均依赖于Emit:
(.NET JSON操作库)Json.NET/Newtonsoft.Json: github地址
(轻量ORM)Dapper:gituhb地址
(ObjectToObjectMapper)EmitMapper:github地址
(AOP库)Castle.DynamicProxy:github地址
学习Emit:
.NET官方文档:https://docs.microsoft.com/zh-cn/dotnet
.NET API浏览器:https://docs.microsoft.com/zh-cn/dotnet/api
之后作者将继续讲解.NET Emit的相关内容和应用,感谢阅读