MSIL实用指南-Action的生成和调用
MSIL实用指南-Action的生成和调用
System.Action用于封装一个没有参数没有返回值的方法。这里生成需要Ldftn指令。
下面讲解怎生成如下的程序。
class ActionTest
{
public static void RunAction(Action act)
{
act();
} public static void TestRunAction()
{
Action act = () => { Console.WriteLine("Test Action"); };
RunAction(act);
}
}
一.Action的调用
Action有方法Invoke,只要加载对象,调用Invoke方法就可以了。
实例代码:
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Callvirt, typeof(Action).GetMethod("Invoke", new Type[] { }));
二、生成Lamda表示式
这里的Lamda表示式即一个匿名方法,它只有一条语句。
所以这样生成:
lambdaMethod = typeBuilder.DefineMethod("<LambdaMethod>",
MethodAttributes.Private| MethodAttributes.Static,
typeof(void), new Type[] { });
ILGenerator ilGenerator = lambdaMethod.GetILGenerator();
ilGenerator.EmitWriteLine("Test Action");
ilGenerator.Emit(OpCodes.Ret);
三、生成Action实例
Action是委托,它需要使用Ldftn和Newobj指令生成实例
实例代码
ilGenerator.Emit(OpCodes.Ldnull);//静态方法加载null,实例方法加载arg_0
ilGenerator.Emit(OpCodes.Ldftn, lambdaMethod);
ilGenerator.Emit(OpCodes.Newobj, typeof(Action).GetConstructors()[]);
完整程序:
using System;
using System.Reflection;
using System.Reflection.Emit; namespace LX1_ILDemo
{
class Demo28_Action
{
static string binaryName = "Demo28_Action.exe";
static string namespaceName = "LX1_ILDemo";
static string typeName = "Demo28"; static AssemblyBuilder assemblyBuilder;
static ModuleBuilder moduleBuilder;
static TypeBuilder typeBuilder;
static MethodBuilder mainMethod;
static MethodBuilder runActionMethod;
static MethodBuilder lambdaMethod; static void Emit_TestMethod()
{
runActionMethod = typeBuilder.DefineMethod("RunAction", MethodAttributes.Public
| MethodAttributes.Static, typeof(void), new Type[] { typeof(Action) });
ILGenerator ilGenerator = runActionMethod.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Callvirt, typeof(Action).GetMethod("Invoke", new Type[] { }));
ilGenerator.Emit(OpCodes.Ret);
} public static void Generate()
{
InitAssembly();
typeBuilder = moduleBuilder.DefineType(namespaceName + "." + typeName, TypeAttributes.Public); Emit_TestMethod();
GenerateMain(); assemblyBuilder.SetEntryPoint(mainMethod, PEFileKinds.ConsoleApplication);
SaveAssembly();
Console.WriteLine("生成成功");
} static void GenerateLambda()
{
lambdaMethod = typeBuilder.DefineMethod("<LambdaMethod>",
MethodAttributes.Private| MethodAttributes.Static,
typeof(void), new Type[] { });
ILGenerator ilGenerator = lambdaMethod.GetILGenerator();
ilGenerator.EmitWriteLine("Test Action");
ilGenerator.Emit(OpCodes.Ret);
} static void GenerateMain()
{
mainMethod = typeBuilder.DefineMethod("Main", MethodAttributes.Public
| MethodAttributes.Static, typeof(void), new Type[] { });
ILGenerator ilGenerator = mainMethod.GetILGenerator(); LocalBuilder localBuilderv1 = ilGenerator.DeclareLocal(typeof(Action)); GenerateLambda();
ilGenerator.Emit(OpCodes.Ldnull);//静态方法加载null,实例方法加载arg_0
ilGenerator.Emit(OpCodes.Ldftn, lambdaMethod);
ilGenerator.Emit(OpCodes.Newobj, typeof(Action).GetConstructors()[]);
ilGenerator.Emit(OpCodes.Stloc_0); ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Call, runActionMethod); EmitReadKey(ilGenerator); ilGenerator.Emit(OpCodes.Ret);
} static void EmitReadKey(ILGenerator ilGenerator)
{
MethodInfo readKeyMethod = typeof(Console).GetMethod("ReadKey", new Type[] { });
ilGenerator.Emit(OpCodes.Call, readKeyMethod);
ilGenerator.Emit(OpCodes.Pop);
} static void InitAssembly()
{
AssemblyName assemblyName = new AssemblyName(namespaceName);
assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name, binaryName);
} static void SaveAssembly()
{
Type t = typeBuilder.CreateType(); //完成Type,这是必须的
assemblyBuilder.Save(binaryName);
}
}
}
MSIL实用指南-Action的生成和调用的更多相关文章
- MSIL实用指南-闭包的生成和调用
闭包(Closure)是词法闭包(Lexical Closure)的简称.对闭包的具体定义有很多种说法,这些说法大体可以分为两类: 一种说法认为闭包是符合一定条件的函数,比如参考资源中这样定义闭包:闭 ...
- MSIL实用指南-struct的生成和操作
struct(结构)是一种值类型,用于将一组相关的信息变量组织为一个单一的变量实体.所有的结构都继承自System.ValueType类,因此是一种值类型,也就是说,struct实例分配在线程的堆栈( ...
- MSIL实用指南-类相关生成
一.创建class用MethodBuilder的DefineType方法,可以指定父类,得到一个TypeBuilder对象. 二.实现继承接口用TypeBuilder的AddInterfaceImpl ...
- MSIL实用指南-this的生成
C#关键字是非静态方法体内部,用Ldarg_0指代this例子ilGenerator.Emit(OpCodes.Ldarg_0);
- MSIL实用指南-生成索引器
MSIL实用指南-生成索引器 索引器是一种特殊的属性,它有参数的,也有get和set方法,属性名称一般是"Item",并且方法名称一般名称是"get_Item" ...
- MSIL实用指南-生成属性
本篇讲解怎么生成属性,包括get和set方法. 第一步,生成一个字段生成字段用TypeBuilder.DefineField方法.实例代码: FieldBuilder customerNameBldr ...
- MSIL实用指南-生成构造函数
本篇讲解生成构造函数的一些知识,包括创建实例构造函数.静态构造函数.调用父类构造函数. 生成构造函数的方法生成构造函数的方法是TypeBuilder.DefineConstructor(MethodA ...
- MSIL实用指南-生成if...else...语句
if...else...语句是非常重要的选择语句,它的生成一般需要ILGenerator的DefineLabel方法和MarkLabel方法,以及Brtrue_S和Br_S指令. 一.DefineLa ...
- MSIL实用指南-生成foreach语句
foreach可以迭代数组或者一个集合对象.foreach语句格式是它的生成步骤是foreach (<成员> in <集合>) <循环体> 一.声明三个变量,loc ...
随机推荐
- 云计算:Linux运维核心管理命令详解
云计算:Linux运维核心管理命令详解 想做好运维工作,人先要学会勤快: 居安而思危,勤记而补拙,方可不断提高: 别人资料不论你用着再如何爽那也是别人的: 自己总结东西是你自身特有的一种思想与理念的展 ...
- JAVA-Spring框架之IOC(DI)(1)
spring框架概述 spring是一个service层的框架,可以整合许多其 他框架,进行工作 spring的主要技术是IOC(DI)和AOP IOC(DI)-控制反转(依赖注入)AOP - 面向切 ...
- paddlepaddle实现猫狗分类
目录 1.预备工作 1.1 数据集准备 1.2 数据预处理 2.训练 2.1 模型 2.2 定义训练 2.3 训练 3.预测 4.参考文献 声明:这是我的个人学习笔记,大佬可以点评,指导,不喜勿喷.实 ...
- three出现状态200的报错
报错代码如下: {status: 200, data: {…}} "sa_SpringUserFindOneView_findPbUserByUserId"header.vue?1 ...
- Docker 入门及安装[Docker 系列-1]
docker 如日中天,这不是单纯的炒概念,docker 确确实实解决了开发与运维的痛点,因此在企业开发中得到了非常广泛的使用,本文对于 docker 的这些基本知识点再做一些简单回顾. 什么是 do ...
- Jmeter之CSS选择器/JQuery选择器关联
选择器: CSS选择器或JQuery选择器是Jmeter支持的两种语法,下面对其两种语法进行简单介绍 CSS选择器 JQuery选择器 Chrome - 复制CSS选择器 Google Chrome在 ...
- 【NOI 2015】程序自动分析 并查集与离散化处理
题目描述 在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足. 考虑一个约束满足问题的简化版本:假设x1,x2,x3,-代表程序中出现的变量,给定n个形如xi=xj或xi≠xj的变量 ...
- python3 编译安装
前言: Linux下大部分系统默认自带python2.x的版本,最常见的是python2.6或python2.7版本,默认的python被系统很多程序所依赖,比如centos下的yum就是python ...
- Fragment 使用详解
极力推荐文章:欢迎收藏 Android 干货分享 阅读五分钟,每日十点,和您一起终身学习,这里是程序员Android 本篇文章主要介绍 Android 开发中的部分知识点,通过阅读本篇文章,您将收获以 ...
- IdentityServer4笔记整理(更新中)
1 OAuth 2.0 1.1 OAuth 2.0协议流程图 1.2 授权码模式 1.3 简化模式 1.4 资源所有者密码模式 1.5 客户端凭证模式 2 OpenID Connect(OIDC) 2 ...