zoukankan      html  css  js  c++  java
  • 基础才是重中之重~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" });
            }

    回到目录

  • 相关阅读:
    vue之路由的命名视图实现经典布局
    vue之路由的嵌套 子路由
    AngularJS阻止事件冒泡$event.stopPropagation()
    Vue之路由规则中定义参数 传参方式2 params
    前台页面中的Cookie存取删除,以及Cookie的跨域问题
    关于Cookie中的Expire问题和删除Cookie那点事儿
    4-索引中的那些操作
    3-在字符串内插中的神奇用法
    2-for循环之特别的写法与神奇的Override
    1-在C#中的数字 int double
  • 原文地址:https://www.cnblogs.com/lori/p/6143004.html
Copyright © 2011-2022 走看看