前言:

Emit 是开发者在掌握反射的使用后,进阶需要的知识,它能显著的改善因反射带来的性能影响。

目前能搜到的 Emit 的相关文章,都是一篇系列,通常推荐对照着反绎后的 IL 编写 Emit 代码,门槛太高。

借着优化 CYQ.Data 时使用 Emit 的心得体会及记忆,写个简单的入门教程,以帮助后来者相对系统的了解及掌握这一块知识。

入门教程的大纲:

第一部分:Emit介绍

第二部分:构建动态程序集

第三部分:构建模块(Module

第四部分:构建类型(Type

第五部分:动态生成方法

第五部分:IL 指令

第六部分:实战项目

第七部分:性能优化与注意事项

每个部分的内容,根据情况,可能一篇介绍或拆分成多章节介绍。

下面开始这个这个系列的第一篇吧:

什么是 Emit

在.NET开发中,Emit 是一种动态生成IL代码的技术,通过使用 System.Reflection.Emit 命名空间中的类,可以在运行时创建和修改程序集、类型和方法。

这种技术为开发人员提供了一种强大的方式来在运行时动态生成和执行代码:

Emit 技术通常用于解决需要在运行时动态生成代码的特定场景,例如在ORM(对象关系映射)框架中动态创建实体类,或者在AOP(面向切面编程)中动态创建代理类。

使用 Emit 技术,可以直接操作IL(Intermediate Language,中间语言)代码,而不是使用传统的编写源代码和编译的方式。

IL代码是一种与平台无关的低级语言,它是在.NET运行时执行的指令集。

通过使用Emit,我们可以以一种更底层的方式来控制代码的生成和执行过程。

Emit技术的核心是 System.Reflection.Emit 命名空间中的 TypeBuilder 和 MethodBuilder 类。

TypeBuilder类允许我们在运行时动态创建新的类型。

MethodBuilder类允许我们在运行时动态创建新的方法。

通过这些类,我们可以定义类型的结构、成员和方法,并使用IL生成器(ILGenerator)来编写实际的IL代码。

使用Emit技术的步骤通常包括以下几个步骤:

  1. 创建一个动态程序集(AssemblyBuilder)。
  2. 在程序集中创建一个动态模块(ModuleBuilder)。
  3. 在模块中创建一个动态类型(TypeBuilder)。
  4. 在类型中创建动态方法(MethodBuilder)。
  5. 使用ILGenerator编写实际的IL代码,包括加载、存储和计算等操作。
  6. 完成IL代码的生成后,使用CreateType方法将动态类型创建为实际的类型。
  7. 最后,通过反射或创建委托或其他方式,可以在运行时调用动态生成的方法。

更通常情况下,使用创建动态方法更常见,即从第4步开始,使用 DynamicMethod 直接创建动态方法。

Emit 技术的优势在于它提供了对IL代码的直接控制,使开发人员能够灵活地生成和修改代码逻辑。

这种动态生成代码的能力在某些特定场景下非常有用,例如需要在运行时根据不同条件生成不同代码的情况。

Emit 的作用和优势

Emit 作为.NET开发中的一项重要技术,具有诸多作用和优势。

作用

  1. 动态代码生成:允许开发人员在运行时动态生成IL代码,包括创建程序集、类型和方法。

  2. ORM框架:在ORM(对象关系映射)框架中,Emit 技术常被用于动态创建实体类,或构建SQL执行语句。

  3. AOP编程:面向切面编程(AOP)通常需要动态创建代理类来实现横切关注点的功能。Emit 技术可以在运行时动态生成代理类,并在其中添加所需的横切逻辑,从而实现AOP编程的目标。

  4. 其它:......。

优势

  1. 灵活性:Emit 技术赋予了开发人员更高级别的灵活性,他们可以根据具体需求动态生成和执行代码。

  2. 性能优势:通过 Emit 技术生成的代码通常可以实现更高的性能,因为它直接操作IL代码,避免了一些动态语言或解释语言的性能损失。

  3. 动态代理:在AOP编程中,Emit 技术可以帮助实现动态代理,从而实现横切关注点的功能。

  4. 底层控制:通过Emit 技术,开发人员可以直接操作IL代码,实现对代码生成和执行过程的更底层控制。

Emit 技术在.NET开发中具有重要的作用和诸多优势,为开发人员提供了一种强大的动态代码生成和执行的方式。

总结:

Emit 技术是一种强大的动态生成IL代码的技术,通过使用 System.Reflection.Emit 命名空间中的类,开发人员可以在运行时创建和修改程序集、类型和方法。

它为开发人员提供了更高级别的灵活性,使他们能够根据需要动态生成和执行代码。

.NET Emit 入门教程:第一部分:Emit 介绍的更多相关文章

  1. WPF入门教程系列三——Application介绍(续)

    接上文WPF入门教程系列二——Application介绍,我们继续来学习Application 三.WPF应用程序的关闭 WPF应用程序的关闭只有在应用程序的 Shutdown 方法被调用时,应用程序 ...

  2. Docker入门教程(一)介绍

    http://dockone.io/article/101 Docker入门教程(一)介绍 [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第一篇,介绍了 ...

  3. 《进击吧!Blazor!》系列入门教程 第一章 8.部署

    <进击吧!Blazor!>是本人与张善友老师合作的Blazor零基础入门教程视频,此教程能让一个从未接触过Blazor的程序员掌握开发Blazor应用的能力. 视频地址:https://s ...

  4. Arduino可穿戴开发入门教程Arduino开发环境介绍

    Arduino可穿戴开发入门教程Arduino开发环境介绍 Arduino开发环境介绍 Arduino不像我们使用的PC端操作系统一样,可以直接在操作系统中安装软件为操作系统编程.Arduino的软件 ...

  5. CPF 入门教程 - 各个控件介绍(八)

    CPF C#跨平台桌面UI框架 系列教程 CPF 入门教程(一) CPF 入门教程 - 数据绑定和命令绑定(二) CPF 入门教程 - 样式和动画(三) CPF 入门教程 - 绘图(四) CPF 入门 ...

  6. WPF入门教程系列二——Application介绍

    一.Application介绍 WPF和WinForm 很相似, WPF与WinForm一样有一个 Application对象来进行一些全局的行为和操作,并且每个 Domain (应用程序域)中仅且只 ...

  7. CodeIgniter框架入门教程——第一课 Hello World!

    本文转载自:http://www.softeng.cn/?p=45 今天开始,我将在这里连载由我自己编写的<CodeIgniter框架入门教程>,首先,这篇教程的读着应该是有PHP基础的编 ...

  8. 《进击吧!Blazor!》系列入门教程 第一章 6.安全

    <进击吧!Blazor!>是本人与张善友老师合作的Blazor零基础入门教程视频,此教程能让一个从未接触过Blazor的程序员掌握开发Blazor应用的能力. 视频地址:https://s ...

  9. 《进击吧!Blazor!》系列入门教程 第一章 7.图表

    <进击吧!Blazor!>是本人与张善友老师合作的Blazor零基础入门教程视频,此教程能让一个从未接触过Blazor的程序员掌握开发Blazor应用的能力. 视频地址:https://s ...

  10. storm入门教程 第一章 前言[转]

    1.1   实时流计算 互联网从诞生的第一时间起,对世界的最大的改变就是让信息能够实时交互,从而大大加速了各个环节的效率.正因为大家对信息实时响应.实时交互的需求,软件行业除了个人操作系统之外,数据库 ...

随机推荐

  1. MySQL创建函数报错:1418 - This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled

    创建函数时报错: 1418 - This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaratio ...

  2. TDD学习笔记(二)单元测试

    单元测试 定义 单元测试最早来源于Kent Beck,他在开发SmallTalk中引入了这个概念,随着软件工程学的不断发展,使得单元测试已经成为软件编程中一项非常有用的实践. 在维基百科中," ...

  3. es6 快速入门 系列 —— 解构

    其他章节请看: es6 快速入门 系列 解构 我们经常使用数组或对象存储数据,然后从中提取出相关数据信息 试图解决的问题 以前开发者为了从对象或数组中提取出特定数据并赋值给变量,编写了很多重复的代码, ...

  4. 延时队列 DelayQueue

    当用户超时未支付时,给用户发提醒消息.另一种场景是,超时未付款,订单自动取消.通常,订单创建的时候可以向延迟队列种插入一条消息,到时间自动执行.其实,也可以用临时表,把这些未支付的订单放到一个临时表中 ...

  5. oracle authid current_user详解

    在编写PLSQL程序时,对于授权的考虑很重要.ORACLE PLSQL中提供两种授权选择: --AUTHID DEFINER (定义者权限):指编译存储对象的所有者.也是默认权限模式. --AUTHI ...

  6. FFmpeg开发笔记(七):ffmpeg解码音频保存为PCM并使用软件播放

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  7. 项目实战:Qt+ffmpeg摄像头检测工具

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  8. go语言中的数据类型

    数据类型可分为四类 基础类型 数字.字符串和布尔型 复合类型 数组.结构体 引用类型 指针.切片.map.函数.通道channel 接口类型 interface

  9. 【算法day1】复杂度和简单排序算法(1)

    复杂度和简单排序算法 时间复杂度 以一个排序(选择排序)操作举例 假设我有一个数组,我要找出其中的最小值放到0的位置上 那么 第一次我会遍历数组中N个数(在0位置处),找出最小的数交换到0位置[看了( ...

  10. Golang标准库——io

    原文:Golang标准库--io 1.io io包提供了对I/O原语的基本接口.本包的基本任务是包装这些原语已有的实现(如os包里的原语),使之成为共享的公共接口,这些公共接口抽象出了泛用的函数并附加 ...