首页 > 代码库 > ILGenerator.Emit动态 MSIL编程(一)

ILGenerator.Emit动态 MSIL编程(一)

  首先在Framework中,Emit相关的类基本都存在于System.Reflection.Emit命名空间下。可见Emit是作为反射的一个元素存在的。

Emit能够实现什么?为什么要学习Emit?首先Emit是C#实现动态代理最佳的方式.动态代理技术也是AOP的思想精髓。现在一些主流的

ORM框架也集成了动态代理的设计思想。对于我们了解认识框架是完全有必要学习的。

   这一节属于入门基础级别:看C#一段代码:

   public int Sum()

   {
       int a = 1;
       int b = 2;
      int c = a + b;
      return c;
  }

  使用IL反汇编程序如下图查看这段代码的IL代码:

  

写出生成这个代码的动态的DLL 代码如下:

public static void SetValue()
{
  #region
  var asmName = new AssemblyName("Test");
  var asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);//创建程序集
  var mdlBldr = asmBuilder.DefineDynamicModule("Test", "Test.dll");//定义模块
  var typeBldr = mdlBldr.DefineType("ILTest", TypeAttributes.Public);//定义类
  var methodBldr = typeBldr.DefineMethod("Sum", MethodAttributes.Public, typeof(int), null);//定义方法
  var il = methodBldr.GetILGenerator();//获取il生成器
  #endregion
  //IL注册变量
  il.DeclareLocal(typeof(int));
  il.DeclareLocal(typeof(int));
  var i=il.DeclareLocal(typeof(int));
  Label lbl = il.DefineLabel();
  il.Emit(OpCodes.Ldc_I4_1);
  il.Emit(OpCodes.Stloc_0);
  il.Emit(OpCodes.Ldc_I4_2);
  il.Emit(OpCodes.Stloc_1);
  il.Emit(OpCodes.Ldloc_0);
  il.Emit(OpCodes.Ldloc_1);
  il.Emit(OpCodes.Add);
  il.Emit(OpCodes.Stloc, i);
  il.Emit(OpCodes.Br_S, lbl);
  il.MarkLabel(lbl);
  il.Emit(OpCodes.Ldloc, i);
  il.Emit(OpCodes.Ret);
  typeBldr.CreateType();
  asmBuilder.Save("Test.dll");//方便反编译 看代码写的对不对
}

编译生成 DLL 如下图:

使用反编译工具打开这个DLL文件如下图:

后面将会介绍Emit注册 属性 ,变量等常用功能.希望喜欢这部分技术的人也可以多多分享一下自己的研究成果。