你需要一点点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