.NET расширенных функций -Emit (1)

  В больших данных / облачные вычисления / исследования искусственного интеллекта и эпоха развития популярности, рост агрессии 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的相关内容和应用,感谢阅读

рекомендация

отwww.cnblogs.com/billming/p/emit-study.html