Emit动态生成代码
2014-11-26 09:47
260 查看
[b]Emit动态生成代码[/b]
引用:秒懂C#通过Emit动态生成代码首先需要声明一个程序集名称,
// 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反编译成代码,
using System; public class HelloKittyClass { public static void SayHelloMethod() { Console.WriteLine("Hello, Kitty!"); Console.ReadLine(); } }
运行结果,
![](http://images.cnitblog.com/blog/175043/201306/01142217-c7cf053609504c759a50724d935dc57c.png)
完整代码
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生成构造函数和属性
相关文章推荐
- 代码生成的思考:MyMeta提供数据库架构,反射、Emit提供构建的提供动态创建的环境
- 秒懂C#通过Emit动态生成代码 C#使用Emit构造拦截器动态代理类
- 秒懂C#通过Emit动态生成代码
- 第12章 动态代码生成和编译技术
- 代码动态生成利器ASM
- 代码动态生成利器ASM
- JAVA根据模板将动态内容生成静态网页的代码
- 用.Net的动态代码生成功能实现AOP
- 动态生成JAVA代码
- 如何动态生成代码?
- ASP动态生成的javascript表单验证代码
- 保存: 运行期间生成代码的动态执
- 使用CODEDOM动态实现代码的生成,编译
- ASP动态生成的javascript表单验证代码
- 动态生成JAVA代码(二)
- 动态生成JAVA代码(二)
- .NET下几种动态生成代码方式比较
- 动态生成JAVA代码(一)
- 想完全使用代码动态生成GridView真难
- 再来个专门为google量身定做的sitemap生成代码,(可是动态的哦)