基础才是重中之重~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" });
        }

回到目录

时间: 2024-11-08 17:21:35

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

Java基础学习笔记十二 类、抽象类、接口作为方法参数和返回值以及常用API

不同修饰符使用细节 常用来修饰类.方法.变量的修饰符 public 权限修饰符,公共访问, 类,方法,成员变量 protected 权限修饰符,受保护访问, 方法,成员变量 默认什么也不写 也是一种权限修饰符,默认访问, 类,方法,成员变量 private 权限修饰符,私有访问, 方法,成员变量 static 静态修饰符 方法,成员变量 final 最终修饰符 类,方法,成员变量,局部变量 abstract 抽象修饰符 类 ,方法 我们编写程序时,权限修饰符一般放于所有修饰符之前,不同的权限修饰

JAVA 类中方法参数与返回值

无参无返回值的方法,用public void 方法名,来声明: 有参无返回值的方法,用public void 方法名,来声明: 有参有返回值的方法,用public int 方法名(int i,int n),来声明(int 是参数的数据类型指定,也可以是其它数据类型,例如:String.char.double.int). 实例: //定义类 public class Test{ //无参无返回值的方法 public void eat(){ System.out.println("我在吃饭.&quo

MVC – 6.Controller Action方法参数与返回值

6.1 Controller接收浏览器数据 a.获取Get数据 : a1:获取路由url中配置好的制定参数: 如配置好的路由: 浏览器请求路径为: /User/Modify/1 ,MVC框架获取请求后,就会找到匹配的路由映射路径url,得知是请求的控制器类 User里的Modify方法,此时就会检查此方法是否包含一个名为 id 的参数,如果有,按照配置的url 获取"参数"{id},并传给此方法. a2.直接通过请求上下文对象里的 Request获取url ?后的的参数: 浏览器请求路

基础才是重中之重~再说面向接口的编程

之前在我的文章中有对接口进行过讲解,但感觉讲的还是不够清晰,不够利针见血,这次我把面向接口的编程里,自认为比较核心的两点说一下: 接口详细介绍请看我的这篇文章 基础才是重中之重~为什么C#有显示实现接口 一切依赖于抽象,而不是实现 多个接口相同的行为,被一个对象实现 #region 多个接口相同的行为,被一个对象实现(一切依赖于抽象,而不是实现) interface IPainter { void Draw(); } interface ICowBoy { void Draw(); } clas

Java基础---Java中无参数带返回值方法的使用(三十七)

Java 中无参带返回值方法的使用 如果方法不包含参数,但有返回值,我们称为无参带返回值的方法. 例如:下面的代码,定义了一个方法名为 calSum ,无参数,但返回值为 int 类型的方法,执行的操作为计算两数之和,并返回结果 在 calSum( ) 方法中,返回值类型为 int 类型,因此在方法体中必须使用 return 返回一个整数值. 调用带返回值的方法时需要注意,由于方法执行后会返回一个结果,因此在调用带返回值方法时一般都会接收其返回值并进行处理.如: 运行结果: 不容忽视的"小陷阱&

速战速决 (3) - PHP: 函数基础, 函数参数, 函数返回值, 可变函数, 匿名函数, 闭包函数, 回调函数

[源码下载] 作者:webabcd 介绍速战速决 之 PHP 函数基础 函数参数 函数返回值 可变函数 匿名函数 闭包函数 回调函数 示例1.函数的相关知识点 1(基础)function/function1.php <?php /** * 函数的相关知识点 1(基础) */ // 可以在相关的 function 声明语句之前调用该函数 f1(); function f1() { echo "f1"; echo "<br />"; } // 这里调用

Java加载jar文件并调用jar文件当中有参数和返回值的方法

在工作当中经常遇到反编译后的jar文件,并要传入参数了解其中的某些方法的输出,想到Java里面的反射可以实现加载jar文件并调用其中的方法来达到自己的目的.就写了个Demo代码. 以下的类可以编译生成hello.jar文件. 1 package org.lele.fatpanda; 2 3 public class Util 4 { 5 public static String myName; 6 /* 7 * 无参数,无返回值的方法. 8 */ 9 public static void get

dwr处理参数或返回值为pojo对象的JavaBean方法

在使用dwr避免不了碰到javabean中有对象作为参数的,那么这样的方法怎么在js中调用呢? 就这个问题,做了一个小例子,与大家分享一下: package com.tgb.dwr; /** * dwr使用测试 * @author Admin * */ public class DwrTest { public String hellobody(User user){ return "Hello,"+user.getName()+",恭喜你今年"+user.getA

RhinoMock中有参数方法和无返回值方法的使用

无返回值方法,RhinoMock的例子是这么做的: demo.VoidThreeArgs(0, "", 0f); LastCall.On(demo).Callback<int, string, float>(ThreeArgsAreSame); mocks.Replay(demo); 无参数方法: INameSource nameSource = (INameSource)mocks.StrictMock(typeof(INameSource)); Expect.Call(