之前看過Dapper(使用到了Emit), CYQ.Data(另一種思路,沒有使用Emit)類的框架之後, 也想自己做一個小框架玩一下, 不過此時能力太過欠缺, 做不了Cyq.Data或者PDF.Net此類的框架, 所以開始了學習之路. 先制定一個能達到的小目標吧, 從Emit開始. 一、使用場景 ...
之前看過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 (若侵權, 請與我聯繫, 刪除此部分內容)
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