博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基础才是重中之重~Emit动态构建方法(参数和返回值)
阅读量:6707 次
发布时间:2019-06-25

本文共 3747 字,大约阅读时间需要 12 分钟。

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

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

[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" });        }

转载于:https://www.cnblogs.com/lori/p/6143004.html

你可能感兴趣的文章
语言模型预训练方法(ELMo、GPT和BERT)——自然语言处理(NLP)
查看>>
Master Nginx(7) - Nginx for the Developer
查看>>
http https
查看>>
IntelliJ IDEA svn 提交错误
查看>>
打印dot模板自动添加表格
查看>>
回溯算法理解
查看>>
Linux命令操作--删除文件
查看>>
ASP.NET 动态创建文本框 TextBox (add TextBox to page dynamically)
查看>>
xcode删除了了文件导致编译之后显示的svn红色警告怎么去除
查看>>
6月份文章分类汇总
查看>>
MVC 返回ActionResult 类型
查看>>
HDU 2089 不要62 (数位DP)题解
查看>>
C++知识回顾(二)——名称空间
查看>>
Poj2031--Building a Space Station(Prim )
查看>>
【转载】已知经纬度查询Landsat TM 、ETM+ 、MSS 数据的行带 整理版 V1.0
查看>>
AE开发的一个想法
查看>>
vsftpd
查看>>
自签名证书和私有CA签名的证书的区别 创建自签名证书 创建私有CA 证书类型 证书扩展名(转)...
查看>>
吴恩达课后作业学习2-week1-1 初始化
查看>>
Phone List
查看>>