首页 > 代码库 > Emit动态生成代码
Emit动态生成代码
Emit动态生成代码
引用:秒懂C#通过Emit动态生成代码
首先需要声明一个程序集名称,
// specify a new assembly namevar 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 buildervar methodBuilder = typeBuilder.DefineMethod( "SayHelloMethod", MethodAttributes.Public | MethodAttributes.Static, null, null); // then get the method il generatorvar il = methodBuilder.GetILGenerator(); // then create the method functionil.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 typevar helloKittyClassType = typeBuilder.CreateType();
如果当前程序集是可运行的,则设置一个程序入口,
// set entry point for this assemblyassemblyBuilder.SetEntryPoint(helloKittyClassType.GetMethod("SayHelloMethod"));
将动态生成的程序集保存成磁盘文件,
// save assemblyassemblyBuilder.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(); } }}
下载完整代码
进一步阅读使用Emit生成构造函数和属性
Emit动态生成代码
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。