基础才是重中之重~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" });
}
基础才是重中之重~Emit动态构建方法(参数和返回值)的更多相关文章
- Java基础学习笔记十二 类、抽象类、接口作为方法参数和返回值以及常用API
不同修饰符使用细节 常用来修饰类.方法.变量的修饰符 public 权限修饰符,公共访问, 类,方法,成员变量 protected 权限修饰符,受保护访问, 方法,成员变量 默认什么也不写 也是一种权 ...
- JAVA 类中方法参数与返回值
无参无返回值的方法,用public void 方法名,来声明: 有参无返回值的方法,用public void 方法名,来声明: 有参有返回值的方法,用public int 方法名(int i,int ...
- Spring Aop 修改目标方法参数和返回值
一.新建注解 @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Document ...
- 【#】Spring3 MVC (三)---请求处理方法 参数及返回值总结
博客分类: spring MVCJSPServletCC++ @RequestMapping("/xxxx") public String aaa(){ } 在处理用户请求的方 ...
- MVC – 6.控制器 Action方法参数与返回值
6.1 Controller接收浏览器数据 a.获取Get数据 : a1:获取路由url中配置好的制定参数: 如配置好的路由: 浏览器请求路径为: /User/Modify/1 ,MVC框架获 ...
- MVC – 6.控制器 Action方法参数与返回值
6.1 Controller接收浏览器数据 a.获取Get数据 : a1:获取路由url中配置好的制定参数: 如配置好的路由: 浏览器请求路径为: /User/Modify/1 ,MVC框架获取请求后 ...
- JS基础语法---函数---介绍、定义、函数参数、返回值
函数: 把一坨重复的代码封装,在需要的时候直接调用即可 函数的作用: 代码的重用 函数需要先定义,然后才能使用 函数名字:要遵循驼峰命名法 函数一旦重名,后面的会把前面的函数覆盖 Ctrl +鼠标左键 ...
- 2. Bean Validation声明式校验方法的参数、返回值
你必须非常努力,才能干起来毫不费力.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习.关注公众 ...
- WPF MVVM UI分离之《交互与数据分离》 基础才是重中之重~delegate里的Invoke和BeginInvoke 将不确定变为确定系列~目录(“机器最能证明一切”) 爱上MVC3系列~全局异常处理与异常日志 基础才是重中之重~lock和monitor的区别 将不确定变成确定~我想监视我的对象,如果是某个值,就叫另一些方法自动运行 将不确定变成确定~LINQ DBML模型可以对
WPF MVVM UI分离之<交互与数据分离> 在我们使用WPF过程中,不可避免并且超级喜欢使用MVVM框架. 那么,使用MVVM的出发点是视觉与业务逻辑分离,即UI与数据分离 诸如下 ...
随机推荐
- json序列化及反序列化
/// <summary> /// 把对象序列化 JSON 字符串 /// </summary> /// <typeparam name="T"> ...
- Maven打包生成可运行bat/sh脚本文件
利用Maven的appassembler-maven-plugin插件,就可以实现自动打包可运行的脚本,还可以跨平台. <plugin> <groupId>org ...
- jQuery 遍历函数
转载http://www.cnblogs.com/tylerdonet/archive/2013/04/05/3000618.html jQuery 遍历函数包括了用于筛选.查找和串联元素的方法. 函 ...
- bash快捷键
https://linuxtoy.org/archives/bash-shortcuts.html 编辑命令 Ctrl + a :移到命令行首 Ctrl + e :移到命令行尾 Ctrl + f :按 ...
- Hololens 手势事件执行顺序
InteractionManager_SourcePressed (Filename: C:\buildslave\unity\build\artifacts/generated/Metro/runt ...
- 【PostgreSQL】PostgreSQL的安装
到了新公司,新公司的数据库是使用PostgreSQL,第一次学习,第一次安装. 开始安装:
- Python模块之常用模块,反射以及正则表达式
常用模块 1. OS模块 用于提供系统级别的操作,系统目录,文件,路径,环境变量等 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("di ...
- 下载apk文件浏览器会直接打开并显示乱码的问题
今天同事反映他的apk文件在自己的老项目中下载有问题:下载apk文件浏览器会直接打开并显示乱码,在别的项目中就没有问题. 后分析response的content-type发现,老项目的类型是text/ ...
- web api Route属性定义
ASP.NET Web API路由,简单来说,就是把客户端请求映射到对应的Action上的过程.在"ASP.NET Web API实践系列03,路由模版, 路由惯例, 路由设置"一 ...
- 如何创建一个Edge 浏览器扩展
随着微软Windows 10 年度更新的发布,数次延宕的Edge 扩展功能终于得到了官方正式支持.我在我的另外一个博客上发布了如何创建一个Edge 浏览器扩展的博文,链接如下: https://blo ...