秒懂C#通過Emit動態產生代碼

來源:互聯網
上載者:User

首先需要聲明一個程式集名稱,

      // specify a new assembly name      var assemblyName = new AssemblyName("Kitty");

從當前應用程式定義域擷取程式集構造器,

      // create assembly builder      var assemblyBuilder = AppDomain.CurrentDomain        .DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);

有幾種動態程式集構造訪問限制:

  • AssemblyBuilderAccess.Run; 表示程式集可被執行,但不能被儲存。  
  • AssemblyBuilderAccess.Save; 表示程式集可被儲存,但不能被執行。  
  • AssemblyBuilderAccess.RunAndSave; 表示程式集可被儲存並能被執行。
  • AssemblyBuilderAccess.ReflectionOnly; 表示程式集只能用於反射內容環境中,不能被執行。 
  • AssemblyBuilderAccess.RunAndCollect; 表示程式集可以被卸載並且記憶體會被回收。

在程式集中構造動態模組,

      // create module builder      var moduleBuilder = assemblyBuilder.DefineDynamicModule("KittyModule", "Kitty.exe");

模組即是代碼的集合,一個程式集中可以有多個模組。並且理論上講,每個模組可以使用不同的程式設計語言實現,例如C#/VB。
構造一個類型構造器,

      // create type builder for a class      var typeBuilder = moduleBuilder.DefineType("HelloKittyClass", TypeAttributes.Public);

通過類型構造器定義一個方法,擷取方法構造器,獲得方法構造器的IL產生器,通過編寫IL代碼來定義方法功能。

      // create method builder      var methodBuilder = typeBuilder.DefineMethod(        "SayHelloMethod",        MethodAttributes.Public | MethodAttributes.Static,        null,        null);      // then get the method il generator      var il = methodBuilder.GetILGenerator();      // then create the method function      il.Emit(OpCodes.Ldstr, "Hello, Kitty!");      il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));      il.Emit(OpCodes.Call, typeof(Console).GetMethod("ReadLine"));      il.Emit(OpCodes.Pop); // we just read something here, throw it.      il.Emit(OpCodes.Ret);

建立類型,

      // then create the whole class type      var helloKittyClassType = typeBuilder.CreateType();

如果當前程式集是可啟動並執行,則設定一個程式入口,

      // set entry point for this assembly      assemblyBuilder.SetEntryPoint(helloKittyClassType.GetMethod("SayHelloMethod"));

將動態產生的程式集儲存成磁碟檔案,

      // save assembly      assemblyBuilder.Save("Kitty.exe");

此時,通過反編譯工具,將Kitty.exe反編譯成代碼,

 1 using System; 2  3 public class HelloKittyClass 4 { 5     public static void SayHelloMethod() 6     { 7         Console.WriteLine("Hello, Kitty!"); 8         Console.ReadLine(); 9     }10 }

運行結果,

完整代碼
 1 using System; 2 using System.Reflection; 3 using System.Reflection.Emit; 4  5 namespace EmitIntroduction 6 { 7   class Program 8   { 9     static void Main(string[] args)10     {11       // specify a new assembly name12       var assemblyName = new AssemblyName("Kitty");13 14       // create assembly builder15       var assemblyBuilder = AppDomain.CurrentDomain16         .DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);17 18       // create module builder19       var moduleBuilder = assemblyBuilder.DefineDynamicModule("KittyModule", "Kitty.exe");20 21       // create type builder for a class22       var typeBuilder = moduleBuilder.DefineType("HelloKittyClass", TypeAttributes.Public);23 24       // create method builder25       var methodBuilder = typeBuilder.DefineMethod(26         "SayHelloMethod",27         MethodAttributes.Public | MethodAttributes.Static,28         null,29         null);30 31       // then get the method il generator32       var il = methodBuilder.GetILGenerator();33 34       // then create the method function35       il.Emit(OpCodes.Ldstr, "Hello, Kitty!");36       il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));37       il.Emit(OpCodes.Call, typeof(Console).GetMethod("ReadLine"));38       il.Emit(OpCodes.Pop); // we just read something here, throw it.39       il.Emit(OpCodes.Ret);40 41       // then create the whole class type42       var helloKittyClassType = typeBuilder.CreateType();43 44       // set entry point for this assembly45       assemblyBuilder.SetEntryPoint(helloKittyClassType.GetMethod("SayHelloMethod"));46 47       // save assembly48       assemblyBuilder.Save("Kitty.exe");49 50       Console.WriteLine("Hi, Dennis, a Kitty assembly has been generated for you.");51       Console.ReadLine();52     }53   }54 }

View Code

下載完整代碼

進一步閱讀使用Emit產生建構函式和屬性

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.