快速编写和调试 Emit 生成 IL 的代码(1)

  最近项目需要用到动态编译对象。主要场景是通过JSON数据对象,生成动态匿名对象,在通过反射方法使用匿名对象。本文Demo重点方法是 通过定义委托字段 执行委托方法。

一、参考链接

1、Emit学习(1) - HelloWorld
2、动态编译
3、如何快速编写和调试 Emit 生成 IL 的代码

二、准备工作

为了快速编写和调试 Emit,我们需要 ReSharper 全家桶:

  1. ReSharper - 用于实时查看 IL 代码
  2. dotPeek - 免费,用于查看我们使用 Emit 生成的代码,便于对比分析

相比于原生 Visual Studio,有此工具帮助的情况下,IL 的编写速度和调试速度将得到质的提升。(当然,利用这些工具依然只是手工操作,存在瓶颈;如果你阅读完本文之后找到或编写一个新的工具,更快,欢迎与我探讨。)
在这里插入图片描述

三、代码

废话不多,上代码

        public static void ILDemo()
        {
            //获取当前AppDomain
            AppDomain currentAppDomain = AppDomain.CurrentDomain;
            //创建程序集
            AssemblyName assemblyName = new AssemblyName("MyAssembly");
            assemblyName.CultureInfo = System.Globalization.CultureInfo.CurrentCulture; // = "zh-CN" 
            assemblyName.SetPublicKeyToken(new Guid().ToByteArray());
            AssemblyBuilder assBuilder = currentAppDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
            //创建模块
            ModuleBuilder moduleBuilder = assBuilder.DefineDynamicModule("MyAssemblyType");
            //创建类型
            var typeBuilder = moduleBuilder.DefineType("MyAssemblyType.MyClass", TypeAttributes.Public);
            //获取委托方法对象
            var DelegateFunc = GetMethod();
            //构建IL委托字段
            FieldBuilder fldBuilder = typeBuilder.DefineField("DynamicField", DelegateFunc.GetType(), FieldAttributes.Public);
            //构建IL委托方法
            MethodBuilder myMthdBld = typeBuilder.DefineMethod(
                                                "addtest",
                                                MethodAttributes.Public,
                                                typeof(object),
                                                Type.EmptyTypes);
            // 通过方法构建器获取一个MSIL生成器
            ILGenerator ILout = myMthdBld.GetILGenerator();
            ILout.Emit(OpCodes.Nop);

            ILout.Emit(OpCodes.Ldarg_0);
            ILout.Emit(OpCodes.Ldfld, fldBuilder);
            //IL方法中 执行委托方法
            ILout.Emit(OpCodes.Callvirt, DelegateFunc.GetType().GetMethod("Invoke"));
            ILout.Emit(OpCodes.Ret);

            //构建对象
            Type t = typeBuilder.CreateType();
            object o1 = Activator.CreateInstance(t);
            //把委托方法  赋值给  DynamicField字段
            t.GetField("DynamicField").SetValue(o1, DelegateFunc);
            //执行o1 addtest方法
            var result = t.GetMethod("addtest").Invoke(o1, null);
            Console.WriteLine("result = " + result);
            Console.ReadKey();
        }

        public static Delegate GetMethod()
        {
            return (new Func<object>(() =>
            {
                return "我是委托方法";
            }));
        }

四、执行效果

在这里插入图片描述
注:如何查看多参数委托方法,查看此篇文件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值