回到目录

对于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. python 小程序 比较目录间的差异

    比较目录间的差异: I 只按照名称做了比较,如果目录的文件名称相同,但是内容不同脚本认为为相同文件 II 针对目录下面的目录没有循环比较,只是比较了目录的名称 import sys, os def d ...

  2. C# Current thread must be set to single thread apartment (STA) mode before OLE calls can be made

    将箭头指向部分替换为编译器报错的内容即可. 参考文章:https://www.experts-exchange.com/questions/28238490/C-help-needed-Current ...

  3. C# 向listbox添加大量数据项的实践心得

    使用 ListBox.Items.Add 方法添加项时,可以使用 BeginUpdate 方法,以防止每次向列表添加项时控件都重新绘制 ListBox.完成向列表添加项的任务后,调用 EndUpdat ...

  4. ACM ICPC Vietnam National Second Round

    A. Stock Market 枚举哪一天买入,哪一天卖出即可. #include<cstdio> #include<algorithm> using namespace st ...

  5. 面向对象课后深入学习(C++ 类的静态成员详细讲解)

    今天在刚申请了博客,一下午都在写那个随笔,所以说好的来看c++的也放在了最后,下星期就考试了,这个类的静态成员是我不是很懂的,在网上 看到一片很详细的博客考下来回去慢慢看. 在C++中,静态成员是属于 ...

  6. Android图书应用-西游记

    下载App 屏幕截图:          功能介绍:1. 侧边滑动目录导航2. 阅读偏好设置3. 记忆阅读进度 内容介绍: 西游记,中国古典名著,内容分三大部分: 第一部分(一到七回)介绍孙悟空的神通 ...

  7. (转)什么是“黑客” by 王珢

    什么是“黑客” by 王垠很多程序员自豪的把自己叫做“黑客”(hacker),把编程叫做 hack.可是殊不知,其实在最高级的程序员眼里,“黑客”其实是一个贬义词.他们更愿意被叫做“程序员”(prog ...

  8. 【翻译】Express web应用开发 第一章

    本章节是一个对初学者友好的Express介绍.你将学习到Express的基础知识.核心概念和实现一个Express应用的组成部分.现阶段我们不需要做太多的编码,本章节会让你熟悉和习惯Express,为 ...

  9. 我的window10

    前言 这个一时半会写不完,也比较耗费时间,留着以后,每周更新一些新的技巧. 折腾了3天多时间的成果——>window10 的全新桌面,不比苹果差!不要说 windows 不能用 mac . 既然 ...

  10. [IOS]cocoapos 两个ruby源的对比

    最近需要使用一些动态类库,cocoapods比较好用,能帮助管理这些类库,百度一下也能找到很多cocoapods配置方法,这里不赘述,我想要讲的是在配置的时候一般都会推荐这样做 $ gem sourc ...