基础才是重中之重~Emit动态构建方法(参数和返回值)-阿里云开发者社区

开发者社区> mcy247> 正文

基础才是重中之重~Emit动态构建方法(参数和返回值)

简介:
+关注继续查看

对于Emit我们知道它的可以动态构建程序集,类型,方法,属性等,或者说只要手动使用C#创建的东西使用Emit也都可以动态创建它们,Emit由于它的特别之处,所以在很多领域得到了广泛的应用,像最近比较火的AOP技术,它最核心的功能就是方法拦截了,我们使用Emit也是可以实现方法拦截功能的,详细可以看大叔这篇文章《Lind.DDD.Aspects通过Plugins实现方法的动态拦截~Lind里的AOP》。

有参数,没有返回值的方法构建与调用

        [TestMethod]
        public void BulidMethod()
        {
            //得到当前的应用程序域
            AppDomain appDm = AppDomain.CurrentDomain;
            //初始化AssemblyName的一个实例
            AssemblyName an = new AssemblyName();
            //设置程序集的名称
            an.Name = "EmitLind";
            //动态的在当前应用程序域创建一个应用程序集
            AssemblyBuilder ab = appDm.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
            //动态在程序集内创建一个模块
            ModuleBuilder mb = ab.DefineDynamicModule("EmitLind");
            //动态的在模块内创建一个类
            TypeBuilder tb = mb.DefineType("HelloEmit", TypeAttributes.Public | TypeAttributes.Class);
            //动态的为类里创建一个方法
            MethodBuilder mdb = tb.DefineMethod("HelloWord", MethodAttributes.Public, null, new Type[] { typeof(string) });

            //得到该方法的ILGenerator
            ILGenerator ilG = mdb.GetILGenerator();
            ilG.Emit(OpCodes.Ldstr, "Hello:{0}");
            //加载传入方法的参数到堆栈
            ilG.Emit(OpCodes.Ldarg_1);
            //调用Console.WriteLine方法,输出传入的字符
            ilG.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string), typeof(string) }));

            ilG.Emit(OpCodes.Ret);
            //创建类的Type对象
            Type tp = tb.CreateType();
            //实例化一个类
            object ob = Activator.CreateInstance(tp);
            //得到类中的方法,通过Invoke来触发方法的调用..
            MethodInfo mdi = tp.GetMethod("HelloWord");
            mdi.Invoke(ob, new object[] { "Hello Lind" });
        }

有参数,同时有返回值的方法构建与调用

        public void BulidMethodRet()
        {

            //得到当前的应用程序域
            AppDomain appDm = AppDomain.CurrentDomain;
            //初始化AssemblyName的一个实例
            AssemblyName an = new AssemblyName();
            //设置程序集的名称
            an.Name = "EmitLind";
            //动态的在当前应用程序域创建一个应用程序集
            AssemblyBuilder ab = appDm.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
            //动态在程序集内创建一个模块
            ModuleBuilder mb = ab.DefineDynamicModule("EmitLind");
            //动态的在模块内创建一个类
            TypeBuilder tb = mb.DefineType("HelloEmit", TypeAttributes.Public | TypeAttributes.Class);
          
            //动态的为类里创建一个方法
            MethodBuilder mdb = tb.DefineMethod(
                "HelloWorldReturn",
                MethodAttributes.Public,
                typeof(string),
                new Type[] { typeof(string), typeof(string) });

            //得到该方法的ILGenerator
            ILGenerator ilG = mdb.GetILGenerator();
            ilG.Emit(OpCodes.Ldstr, "你好:{0}-{1}");
            //加载传入方法的参数到堆栈
            ilG.Emit(OpCodes.Ldarg_1); 
            ilG.Emit(OpCodes.Ldarg_2);
            //调用Console.WriteLine方法,输出传入的字符
            ilG.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string), typeof(string) ,typeof(string)}));

            // ilG.Emit(OpCodes.Pop);//加这个就有问题了
            //返回值部分
            LocalBuilder local = ilG.DeclareLocal(typeof(string));
            ilG.Emit(OpCodes.Ldstr, "Return Value:{0}");
            ilG.Emit(OpCodes.Ldarg_1);
            ilG.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(string) }));
            ilG.Emit(OpCodes.Stloc_0, local);
            ilG.Emit(OpCodes.Ldloc_0, local);
            ilG.Emit(OpCodes.Ret);
            //创建类的Type对象
            Type tp = tb.CreateType();
            //实例化一个类
            object ob = Activator.CreateInstance(tp);
            //得到类中的方法,通过Invoke来触发方法的调用..
            MethodInfo mdi = tp.GetMethod("HelloWorldReturn");
            mdi.Invoke(ob, new object[] { "Hello Lind","OK" });
        }

本文转自博客园张占岭(仓储大叔)的博客,原文链接:基础才是重中之重~Emit动态构建方法(参数和返回值),如需转载请自行联系原博主。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
MySQL HA架构下innodb_flush_log_at_trx_commit及sync_binlog参数
      HeartBeat + DRBD以及MySQL replication是很多企业比较普遍使用的方式。对于数据的完整性和一致性的问题,这两种架构需要考虑2个重要的参数innodb_flush_log_at_trx_commit以及sync_binlog参数。
1130 0
函数返回值是否使用引用类型的问题:理解引用、返回值
  在《对象更有用的玻璃罩——常引用》一文中,介绍了对象作为函数的参数时,推荐使用引用的形式。并且,如果实际参数的值不允许改变时,声明为常引用更佳。   在《第8周-任务1-方案3-复数类中运算符重载(与实数运算)》中,又讨论了一个问题,结论是:在类似复数加法运算符重载这样的函数,形式参数用作为常引用最佳,如: friend Complex operator + (const
1161 0
c++ ado 调用存储过程并得到输出参数和返回值
// AccessSqlserverByAdo.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include #include #include using namespace std; #import "C:\Program Files\Common Files\System\ado\msado15.
1083 0
使用 TypeScript 改造构建工具及测试用例
最近的一段时间一直在搞TypeScript,一个巨硬出品、赋予JavaScript语言静态类型和编译的语言。 第一个完全使用TypeScript重构的纯Node.js项目已经上线并稳定运行了。 第二个前后端的项目目前也在重构中,关于前端基于webpack的TypeScript套路之前也有提到过:TypeScript在react项目中的实践。
1446 0
# Apache Spark系列技术直播# 第八讲 【 微软Azure平台利用Intel Analytics Zoo构建AI客服支持实践 】
**直播时间**: 2019.01.10(周四) 19:00 - 20:00 **主讲人:** 黄凯——Intel大数据技术团队软件工程师。 卫雨青——Microsoft C+AI 团队软件工程师。
1299 0
+关注
mcy247
做自己的太阳 无需凭借谁的光
1070
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载