引用:秒懂C#經過Emit動態生成代碼html
首先須要聲明一個程序集名稱,git
// specify a new assembly name var assemblyName = new AssemblyName("Kitty");
從當前應用程序域獲取程序集構造器,github
// create assembly builder var assemblyBuilder=AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
有幾種動態程序集構造訪問限制:編程
在程序集中構造動態模塊,編程語言
// 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);
建立類型,ui
// then create the whole class type var helloKittyClassType = typeBuilder.CreateType();
若是當前程序集是可運行的,則設置一個程序入口,this
// set entry point for this assembly assemblyBuilder.SetEntryPoint(helloKittyClassType.GetMethod("SayHelloMethod"));
將動態生成的程序集保存成磁盤文件,spa
// save assembly assemblyBuilder.Save("Kitty.exe");
此時,經過反編譯工具,將Kitty.exe反編譯成代碼,
using System; public class HelloKittyClass { public static void SayHelloMethod() { Console.WriteLine("Hello, Kitty!"); Console.ReadLine(); } }
運行結果,
using System; using System.Reflection; using System.Reflection.Emit; namespace EmitIntroduction { class Program { static void Main(string[] args) { // specify a new assembly name var assemblyName = new AssemblyName("Kitty"); // create assembly builder var assemblyBuilder = AppDomain.CurrentDomain .DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave); // create module builder var moduleBuilder = assemblyBuilder.DefineDynamicModule( "KittyModule", "Kitty.exe"); // create type builder for a class var typeBuilder = moduleBuilder.DefineType( "HelloKittyClass", TypeAttributes.Public); // 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"); Console.WriteLine( "Hi, Dennis, a Kitty assembly has been generated for you."); Console.ReadLine(); } } }