Emit学习(1) - HelloWorld
之前看过Dapper(使用到了Emit), CYQ.Data(另一种思路,没有使用Emit)类的框架之后, 也想自己做一个小框架玩一下, 不过此时能力太过欠缺, 做不了Cyq.Data或者PDF.Net此类的框架, 所以开始了学习之路. 先制定一个能达到的小目标吧, 从Emit开始.
可能很多人还不知道Emit是个什么鬼, 但是听说过EmitMapper的肯定有不少, Emit的概念, 我这里就不多说了, 可以看一下别人的博文(下面的链接里面就有)
一、使用场景
Emit的使用场景了,通常我们在下面几种情形时可以选择使用Emit来实现:
1. 运行中动态的创建类型、模块等,同时又需要提高效率(可以动态编译一次,然后就不用再处理了).
2 .延迟绑定对象的使用。
3 . 工具插件及IDE的开发等。
4. ORM的实现。
5. 减少反射的性能损失。
二、小示例
以下部分转载自 : http://www.cnblogs.com/gjhjoy/p/3627243.html (若侵权, 请与我联系, 删除此部分内容)
static void Main(string[] args)
{
//1.构建程序集
var asmName = new AssemblyName("Test");
var asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave); //2.创建模块
var mdlBldr = asmBuilder.DefineDynamicModule("Elvinle", "Elvinle.exe"); //3.定义类
var typeBldr = mdlBldr.DefineType("Hello", TypeAttributes.Public); //4.定义类成员(方法,属性等等)
//public void SayHello(){}
var methodBldr = typeBldr.DefineMethod("SayHello", MethodAttributes.Public | MethodAttributes.Static, null, null); //5.构建方法体
//获取il生成器
var il = methodBldr.GetILGenerator();
il.Emit(OpCodes.Ldstr, "Hello, HelloWorld!");
il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
il.Emit(OpCodes.Call, typeof(Console).GetMethod("ReadLine"));
il.Emit(OpCodes.Pop);//读入的值会被推送至evaluation stack,而本方法是没有返回值的,因此,需要将栈上的值抛弃
il.Emit(OpCodes.Ret); //调用CreateType来完成类型的创建
var t = typeBldr.CreateType();
//设置入口点为SayHello(), -- 相当于Main()
asmBuilder.SetEntryPoint(t.GetMethod("SayHello"));
asmBuilder.Save("Elvinle.exe");
}
结果如下:

以下部分转载自 : http://www.cnblogs.com/Mervin/archive/2013/04/05/reflection-3.html (若侵权, 请与我联系, 删除此部分内容)
使用Emit常用的几个类如下:
| 类名 | 用途 |
| AssemblyBuilder | 用来定义和创建动态的程序集 |
| ConstructorBuilder | 用来创建动态类的构造函数 |
| CustomAttributeBuilder | 用来创建用户自定义的特性 |
| MethodBuilder | 用来创建动态类的方法,也可创建构造函数,因为构造函数本身也是一个特殊的方法 |
| ModuleBuilder | 用来创建动态程序集中的模块 |
| TypeBuilder | 用来定义和创建动态类的新实例 |
| DynamicMethod | 用来创建可动态编译和执行的动态方法 |
| ILGenerator | 用来生成中间语言,即MSIL指令 |
| OpCodes | 提供 Microsoft 中间语言 (MSIL) 指令的字段表示形式 |
首先来看下使用Emit的一般步骤:
1. 创建一个程序集。
2. 在程序集内创建一个模块。
3. 在模块内创建动态类。
4. 为动态类添加动态方法,属性,事件,等等。
5. 生成相关的IL代码。
6. 返回创建的类型或是持久化保存到硬盘中。
三、指令明细, 有点类似 汇编
由于之前电脑vs安装的是英文版的, 对于一些OpCodes指令, 有一些看的不是很懂, 所以附上一个中文版的吧
地址:http://files.cnblogs.com/files/elvinle/OpCodes.rar
Emit学习(1) - HelloWorld的更多相关文章
- AspectJ基础学习之三HelloWorld(转载)
AspectJ基础学习之三HelloWorld(转载) 一.创建项目 我们将project命名为:aspectjDemo.然后我们新建2个package:com.aspectj.demo.aspect ...
- [Cocos2d-x for WP8学习笔记] HelloWorld结构分析
先来看一下目录结构: Assets:游戏资源文件,图片音频等,Resource文件夹也有类似功能 include:用于放置游戏头文件 Shaders:渲染器着色器文件(大雾) cocos2dorig. ...
- [Cocos2d-x for WP8学习笔记] HelloWorld
Cocos2d-x 是一个支持多平台的 2D 手机游戏引擎,使用 C++ 开发,基于OpenGL ES,基于Cocos2d-iphone,支持 WOPhone, iOS 4.1, Android 2. ...
- System.Reflection.Emit学习
C#反射发出System.Reflection.Emit学习 分享: 1 一.System.Reflection.Emit概述 Emit,可以称为发出或者产生.与Emit相关的类基本都存在于Syste ...
- Emit学习(3) - OpCodes - 动态添加属性、构造函数、方法
上一篇介绍了 IL 的部分, 基础的部分, 暂时就介绍到那里了, 接下来要进入代码编写阶段了. 今天的主题是 在代码运行的过程中, 去动态的创建类, 属性, 方法. 来源:http://www.cnb ...
- Emit学习(2) - IL - 常用指令介绍
学习Emit必不可少的, 会使用到IL中间代码. 初见IL代码, 让我有一种汇编的感觉, 让我想起了, 大学时, 学习8051的汇编语言. 多的就不扯了, 直接进入正题, OpCodes指令集是不是有 ...
- Emit学习(1)-Emit概览
一.Emit概述 Emit,可以称为发出或者产生.在Framework中,与Emit相关的类基本都存在于System.Reflection.Emit命名空间下.可见Emit是作为反射的一个元素存在的. ...
- 从零开始学习C#——HelloWorld(一)
从零开始学习C# 老规矩Hello World 您的第一个程序 visual studio 如何使用就不说了 //编程的开始,Hello World! program in C# using Syst ...
- MSIL学习------从HelloWorld开始
我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=3889z1y72b28 ...
随机推荐
- 人人都是 DBA(VIII)SQL Server 页存储结构
当在 SQL Server 数据库中创建一张表时,会在多张系统基础表中插入所创建表的信息,用于管理该表.通过目录视图 sys.tables, sys.columns, sys.indexes 可以查看 ...
- 字体大小自适应纯css解决方案
viewpoint css3提供了一些与当前viewpoint相关的元素,vw,vh,vim等. “viewpoint” = window size vw = 1% of viewport width ...
- js DOM优化相关探索
我在这尝试两个方面:-->DOM与js -->DOM与浏览器 (最近在秒味视频上学到不少,哈哈哈) 一.DOM与js 1.js与dom的交互问题 频繁的与dom交互,是一件浪费时间与金钱的 ...
- DDD领域驱动设计之聚合、实体、值对象
关于具体需求,请看前面的博文:DDD领域驱动设计实践篇之如何提取模型,下面是具体的实体.聚合.值对象的代码,不想多说什么是实体.聚合等概念,相信理论的东西大家已经知晓了.本人对DDD表示好奇,没有在真 ...
- [异常解决] JTAG 与STM32的SWD连接接线方式
如果我们的板子上只留了4个接口:V3.3,SWDIO,SWDCLK,GND.那么和JTAG的连接关系参见下图: dd400cf22b5c01e57a6c9e198d5383a0_189.jpg (0 ...
- 在设置代理的环境下使用SharePoint CSOM
SharePoint 的CSOM都是通过HttpRequest来实现和SharePoint服务器的交互的,那么我们如何设置HttpWebRequest的一些特性呢,如Cookie,WebProxy? ...
- Senparc.Weixin.MP SDK 微信公众平台开发教程(十):多客服接口说明
微信官方的多客服接口原理是通过用户发送的信息,开发者服务器返回一条指定类型的响应信息,使用户的对话状态切换到官方的多客服状态(持续一段时间),这段时间内用户发送的所有信息都不会到达开发者的服务器,而是 ...
- swift 加载 storyboard 里的UIViewController
let storyBoard:UIStoryboard! = UIStoryboard(name: "Main", bundle: nil) let deskVC:DeskView ...
- Bootstrap~日期控制
回到目录 一个成熟的框架,日期控制是少不了的,在网上也有很多日期控制可以选择,而主框架用了bootstrap,日期控制也当前要用它自己的, 控件地址:http://www.bootcss.com/p/ ...
- WebApi系列~安全校验中的防篡改和防复用
回到目录 web api越来越火,因为它的跨平台,因为它的简单,因为它支持xml,json等流行的数据协议,我们在开发基于面向服务的API时,有个问题一直在困扰着我们,那就是数据的安全,请求的安全,一 ...