之前看过Dapper(使用到了Emit), CYQ.Data(另一种思路,没有使用Emit)类的框架之后, 也想自己做一个小框架玩一下, 不过此时能力太过欠缺, 做不了Cyq.Data或者PDF.Net此类的框架, 所以开始了学习之路. 先制定一个能达到的小目标吧, 从Emit开始.
一、使用场景
Emit的使用场景了,通常我们在下面几种情形时可以选择使用Emit来实现:
1. 运行中动态的创建类型、模块等,同时又需要提高效率(可以动态编译一次,然后就不用再处理了).
2 .延迟绑定对象的使用。
3 . 工具插件及IDE的开发等。
4. ORM的实现。
5. 减少反射的性能损失。
二、小示例
以下部分转载自 : http://www.cnblogs.com/gjhjoy/p/3627243.html (若侵权, 请与我联系, 删除此部分内容)
class Program { 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
时间: 2024-10-13 03:34:45