回到目录

对于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动态构建方法(参数和返回值)的更多相关文章

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

    不同修饰符使用细节 常用来修饰类.方法.变量的修饰符 public 权限修饰符,公共访问, 类,方法,成员变量 protected 权限修饰符,受保护访问, 方法,成员变量 默认什么也不写 也是一种权 ...

  2. JAVA 类中方法参数与返回值

    无参无返回值的方法,用public void 方法名,来声明: 有参无返回值的方法,用public void 方法名,来声明: 有参有返回值的方法,用public int 方法名(int i,int ...

  3. Spring Aop 修改目标方法参数和返回值

    一.新建注解 @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Document ...

  4. 【#】Spring3 MVC (三)---请求处理方法 参数及返回值总结

    博客分类:  spring MVCJSPServletCC++ @RequestMapping("/xxxx") public String  aaa(){ } 在处理用户请求的方 ...

  5. MVC – 6.控制器 Action方法参数与返回值

      6.1 Controller接收浏览器数据   a.获取Get数据 : a1:获取路由url中配置好的制定参数: 如配置好的路由: 浏览器请求路径为: /User/Modify/1 ,MVC框架获 ...

  6. MVC – 6.控制器 Action方法参数与返回值

    6.1 Controller接收浏览器数据 a.获取Get数据 : a1:获取路由url中配置好的制定参数: 如配置好的路由: 浏览器请求路径为: /User/Modify/1 ,MVC框架获取请求后 ...

  7. JS基础语法---函数---介绍、定义、函数参数、返回值

    函数: 把一坨重复的代码封装,在需要的时候直接调用即可 函数的作用: 代码的重用 函数需要先定义,然后才能使用 函数名字:要遵循驼峰命名法 函数一旦重名,后面的会把前面的函数覆盖 Ctrl +鼠标左键 ...

  8. 2. Bean Validation声明式校验方法的参数、返回值

    你必须非常努力,才能干起来毫不费力.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习.关注公众 ...

  9. WPF MVVM UI分离之《交互与数据分离》 基础才是重中之重~delegate里的Invoke和BeginInvoke 将不确定变为确定系列~目录(“机器最能证明一切”) 爱上MVC3系列~全局异常处理与异常日志 基础才是重中之重~lock和monitor的区别 将不确定变成确定~我想监视我的对象,如果是某个值,就叫另一些方法自动运行 将不确定变成确定~LINQ DBML模型可以对

    WPF MVVM UI分离之<交互与数据分离>   在我们使用WPF过程中,不可避免并且超级喜欢使用MVVM框架. 那么,使用MVVM的出发点是视觉与业务逻辑分离,即UI与数据分离 诸如下 ...

随机推荐

  1. sql语句,怎么取查询结果的位置

    SQL 中的 substring 函数是用来抓出一个栏位资料中的其中一部分.这个函数的名称在不同的资料库中不完全一样: MySQL: SUBSTR( ), SUBSTRING( ) Oracle: S ...

  2. Linux学习笔记(15)-信号量

    在多线程或者多进程编程中,有一个非常需要关注的东西,那就是同步以及互斥问题. 同步是指多个进程之间的协作,而互斥是指多个进程之间,为了争夺有限的资源,而进行的竞争. 理论很高端,但经过自己几天的学习, ...

  3. C# 解析JSON的几种办法

    欲成为海洋大师,必知晓海中每一滴水的真名. 刚开始只是想找一个转换JSON数组的方法,结果在MSDN翻到一大把. 搜索过程中免不了碰到一大堆名词:WCF => DataContract => ...

  4. 从零开始山寨Caffe·捌:IO系统(二)

    生产者 双缓冲组与信号量机制 在第陆章中提到了,如何模拟,以及取代根本不存的Q.full()函数. 其本质是:除了为生产者提供一个成品缓冲队列,还提供一个零件缓冲队列. 当我们从外部给定了固定容量的零 ...

  5. Linux Crontab语法

    Crontab语法 Lists 链表值 : 逗号,表示并列,要依次序;Examples:"1,2,5,9", "0-4,8-12". Ranges of num ...

  6. Xpath基础语法学习

    背景: 之所以学习Xpath,是因为在学习selenium定位页面元素,总是定位不到元素.为了更好的开展自动化测试,先学习下Xpath. 一:Xpath是什么. 1:Xpath是一门在XML文档中查找 ...

  7. linux(centos)下挂载ntfs文件系统

    在将硬盘插到Linux系统上,打开硬盘时一直提示:unknown filesystem type 'ntfs'.在尝试网上的方法也遇到了一些问题. 下面按照遇到的问题,按照正确的方式注意操作从而避免问 ...

  8. 通读SDWebImage②--视图分类

    本文目录 UIView+WebCacheOperation UIImageView+WebCache.UIImageView+HighlightedWebCache.MKAnnotationView+ ...

  9. js,css控制网页内容不让选中和复制

    ---恢复内容开始--- JS, CSS控制网页内容不让选择和复制 CSS 控制: <style> body{ -moz-user-select:none;//针对火狐浏览器,谷歌则-we ...

  10. apk 反编译

    http://blog.csdn.net/vipzjyno1/article/details/21039349/ [置顶] Android APK反编译就这么简单 详解(附图) 标签: android ...