你需要一点点CIL

1.当我们程序集中有大量反射的时候,性能往往会下降很快。我们目的很明确 如何解决反射造成的这些影响,其中之一个正确且高逼格的做法是 使用 CIL指令去实现。如何实现需要我们拥有若干基础知识。知道 CIL,JIT基本编译,CLR运行机制,内存分配本质等等不需要太高层次的知识即可!当然你需要知晓若干的指令:例如: ld(入栈) ,st(出栈),conv(数字转换),b/br(条件/无条件 跳转),call(调用)系列。当然  .net 下 OpCodes 类为我们封装了一些东西,可以方便调用。网上创建dll 的Demo
一大把。。。废话不说类似代码如下: 1.构建程序集  2.构建模块  3.构建类  4.方法签名 5.方法实现
6.方法调用
 Demo 如下:

              //程序集
            var assemblyName = new AssemblyName("CCX_PetShop");//创建程序集
            var dllBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, System.Reflection.Emit.AssemblyBuilderAccess.RunAndSave);
            //模块
            var body = dllBuilder.DefineDynamicModule("CCX_Emit", "CCX_Emit.dll");
            //方法
            var bodyClass = body.DefineType("TestEmit", TypeAttributes.Public);//定义类
            //构建 public viod EmitClass(){ }类型;
            var dynamicMethod = bodyClass.DefineMethod("EmitClass", MethodAttributes.Public | MethodAttributes.Static, null, null);
            var ilBuilder = dynamicMethod.GetILGenerator();
            ilBuilder.Emit(OpCodes.Ldstr, "CCX  Emit Reflection");//加载字符串
            ilBuilder.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
            ilBuilder.Emit(OpCodes.Call, typeof(Console).GetMethod("ReadLine"));
            ilBuilder.Emit(OpCodes.Pop);//要将变量值抛弃后续没有使用到
            ilBuilder.Emit(OpCodes.Ret);
            var rundll= bodyClass.CreateType();
            dllBuilder.SetEntryPoint(rundll.GetMethod("EmitClass"));
            dllBuilder.Save("EmitTest.exe");
           //dllBuilder.Save("CCX_Emit.dll");//保存为程序集外面调用


打开 bin debug 下看到了 EmitTest.exe 执行后不出意外的 运行 EmitTest.exe 出现了 CCX  Emit Reflection   。。
PS:就是这么简单的动态构建一个 dll,貌似和我们的目标 用 Emit 方式代替直白的反射 有所差距。还是一步一步来。步子大了容易扯着蛋。一下子贴出来按照人类接受新事物的惯性思维肯定对它是排斥的。

同步的QQ空间博客地址:http://user.qzone.qq.com/2129635526/blog/1458573638

posted on 2016-03-22 13:45  无觉-李敏  阅读(371)  评论(1编辑  收藏  举报