Emit动态生成代码

Emit动态生成代码

引用:秒懂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();
  }
}

运行结果,

完整代码

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生成构造函数和属性

时间: 2024-10-27 19:21:14

Emit动态生成代码的相关文章

动态生成代码中的事件注意事项

var d = '<a href="#" title="查看"  onclick ="ViewById(' + row.Id + ','+"'"+row.vpdm+"'"+')">' + value + '</a>'; "'"+row.vpdm+"'"这里要加上单引号,前面的row.Id是int所以不用,但后面的是字符串类型就得加上单引号,要不

CodeTypeDeclaration,CodeMemberProperty动态生成代码

1 由于是CodeDom些列,所以先介绍几个CodeDom表达式: 2 3 1:CodeConditionStatement:判断语句即是if(condition){} else{},看最全的那个构造函数: 4 5 public CodeConditionStatement( 6 CodeExpression condition,//条件 7 CodeStatement[] trueStatements,//为true的语句体 8 CodeStatement[] falseStatements/

Android 动态生成布局 (多层嵌套)

Android 除了可以加载xml文件,显示布局外,也可以代码生成布局,并通过setContentView(View view)方法显示布局.单独的一层布局,如一个主布局加一个控件(如Button\imageView等)动态生成代码比较简单,下面只给出示例代码: package com.example.android_dongtaishengcheng; import android.os.Bundle; import android.app.Activity; import android.c

在后台代码中动态生成pivot项并设置EventTrigger和Action的绑定

最近在做今日头条WP的过程中,遇到需要动态生成Pivot项的问题.第一个版本是把几个频道写死在xaml里了,事件绑定也写在xaml里,每个频道绑定一个ObservableCollection<ArticleItem>.xaml中一个Pivot项的代码大体如下: <phone:PivotItem Header="热点"> <Grid Margin="12,0,0,0" > <Grid.RowDefinitions> &l

用js动态生成css代码

有时候我们需要利用js来动态生成页面上style标签中的css代码,方法很直接,就是直接创建一个style元素,然后设置style元素里面的css代码,最后把它插入到head元素中.但有些兼容性问题我们需要解决.首先在符合w3c标准的浏览器中我们只需要把要插入的css代码作为一个文本节点插入到style元素中即可,而在IE中则需要利用style元素的styleSheet.cssText来解决.还需要注意的就是在有些版本IE中一个页面上style标签数量是有限制的,如果超过了会报错,需要考虑这点.

如何根据动态SQL代码自动生成DTO

当前的状况 一般做数据库相关开发, 除非学习, 否则很少有人愿意直接使用JDBC.本来Java代码就比较啰嗦了,而直接用JDBC写代码之啰嗦简直有些令人发狂!所以在实际开发过程中,我们通常都会使用一些框架/库来帮助我们操作数据库.而且开源市场上的选择也比较多,就我个人接触到的有:Hibernate,MyBatis,JdbcTemplate,DbUtils,ActiveRecord,JavaLite等等. 这些框架都能大幅的提高开发效率,对于一些基本CRUD操作来说,虽然各有差异,但总的来说基本是

js动态生成css代码

用js动态生成css代码 有时候我们需要利用js来动态生成页面上style标签中的css代码,方法很直接,就是直接创建一个style元素,然后设置style元素里面的css代码,最后把它插入到head元素中.但有些兼容性问题我们需要解决.首先在符合w3c标准的浏览器中我们只需要把要插入的css代码作为一个文本节点插入到style元素中即可,而在IE中则需要利用style元素的styleSheet.cssText来解决.还需要注意的就是在有些版本IE中一个页面上style标签数量是有限制的,如果超

jquery动态生成html代码绑定事件

今天工作中需要在页面动态生成html代码,但发现新生成的代码的click事件失效了(非动态生成的代码已经绑定了click事件),于是在网上找了很多解决办法,很多都比较复杂,且使用的jquery都比较老,于是结合网上加上自己的测试,找到了一种解决方法. 我使用的jquery是1.9.11,jquery1.7之后就将live方法废弃了,新增了on和off方法,我的解决办法就是使用on方法,首先看代码: <div class="h3"> <h3>李健1</h3&

winform WebBrowser控件中,cs后台代码执行动态生成的js

很多文章都是好介绍C# 后台cs和js如何交互,cs调用js方法(js方法必须是页面上存在的,已经定义好的),js调用cs方法, 但如果想用cs里面执行动态生成的js代码,如何实现呢? 思路大致是这样的,cs动态插入js到html上,cs执行html插入的js方法代码. 封装好的方法: /// <summary> /// webbrowser执行脚本 /// </summary> /// <param name="web">传入WebBrowser