MSIL实用指南-生成异常处理
本篇讲解怎么生成异常。C# 异常处理时建立在四个关键词之上的:try、catch、finally 和 throw。
一、异常的抛出
抛出异常在C#语言中要使用throw关键字,使用方法是
throw <一个异常对象>;
和
throw;
1、抛出异常
抛出异常的指令是Throw,它对应的C#使用语句是
throw new <异常类型>;
它的使用格式是
adderIL.ThrowException(<异常Type>);
它的生成步骤是
(1)用newobj指令创一个异常对象
(2)生成Throw指令
2、再次抛出异常
抛出异常的指令是Rethrow,它对应的C#语句是
throw;
这条语句只有一个关键字“throw”和封号,所以它只能用在catch语句块,是把捕捉到的异常再次抛出。
二、异常的处理
C#语言的异常处理是try...catch...finally语句。
它的生成步骤是
1.用DefineLabel创建一个异常处理结束的标签。
2、生成try
这要使用BeginExceptionBlock方法,返回一个Label对象。
3、生成catch
这要使用BeginCatchBlock方法,有一个参数,它代表所要捕捉的异常类型。
实例:
ilGenerator.BeginCatchBlock(typeof(ArgumentNullException));
4、生成finally
这要使用BeginFinallyBlock方法。
5、结束异常
这要使用EndExceptionBlock方法。
6、标记异常处理结束
完整程序:
using System;
using System.Reflection;
using System.Reflection.Emit; namespace LX1_ILDemo
{
class Demo26_TryCatchFinally
{
static string binaryName = "Demo26_TryCatchFinally.exe";
static string namespaceName = "LX1_ILDemo";
static string typeName = "DemoTryCatchFinally"; static AssemblyBuilder assemblyBuilder;
static ModuleBuilder moduleBuilder;
static TypeBuilder typeBuilder;
static MethodBuilder mainMethod;
static MethodBuilder testMethod; static void Emit_TestMethod()
{
testMethod = typeBuilder.DefineMethod("Test", MethodAttributes.Public
| MethodAttributes.Static, typeof(void), new Type[] { typeof(string)});
ILGenerator ilGenerator = testMethod.GetILGenerator(); Label endOfMethodLabel = ilGenerator.DefineLabel(); Label exceptionBlock = ilGenerator.BeginExceptionBlock();
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Call, typeof(int).GetMethod("Parse", new Type[] { typeof(string) }));
ilGenerator.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) }));
//ilGenerator.Emit(OpCodes.Leave_S, endOfMethodLabel); ilGenerator.BeginCatchBlock(typeof(ArgumentNullException));
ilGenerator.Emit(OpCodes.Pop);
ilGenerator.EmitWriteLine("error");
ilGenerator.Emit(OpCodes.Rethrow);
//ilGenerator.Emit(OpCodes.Leave_S, endOfMethodLabel); ilGenerator.BeginFinallyBlock();
ilGenerator.EmitWriteLine("finally");
MethodInfo readKeyMethod = typeof(Console).GetMethod("ReadKey", new Type[] { });
ilGenerator.Emit(OpCodes.Call, readKeyMethod);
ilGenerator.Emit(OpCodes.Pop); ilGenerator.EndExceptionBlock(); ilGenerator.MarkLabel(endOfMethodLabel);
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 GenerateMain()
{
mainMethod = typeBuilder.DefineMethod("Main", MethodAttributes.Public
| MethodAttributes.Static, typeof(void), new Type[] { });
var ilGenerator = mainMethod.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldstr,"10t");
ilGenerator.Emit(OpCodes.Call, testMethod); MethodInfo readKeyMethod = typeof(Console).GetMethod("ReadKey", new Type[] { });
ilGenerator.Emit(OpCodes.Call, readKeyMethod);
ilGenerator.Emit(OpCodes.Pop); ilGenerator.Emit(OpCodes.Ret);
} 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实用指南-生成异常处理的更多相关文章
- MSIL实用指南-生成索引器
MSIL实用指南-生成索引器 索引器是一种特殊的属性,它有参数的,也有get和set方法,属性名称一般是"Item",并且方法名称一般名称是"get_Item" ...
- MSIL实用指南-生成属性
本篇讲解怎么生成属性,包括get和set方法. 第一步,生成一个字段生成字段用TypeBuilder.DefineField方法.实例代码: FieldBuilder customerNameBldr ...
- MSIL实用指南-生成构造函数
本篇讲解生成构造函数的一些知识,包括创建实例构造函数.静态构造函数.调用父类构造函数. 生成构造函数的方法生成构造函数的方法是TypeBuilder.DefineConstructor(MethodA ...
- MSIL实用指南-生成接口
本篇讲解怎么样生成接口,即interface. 一.创建类型创建一个接口类型依旧用ModuleBuilder的DefineType方法,但是它的第二个参数必须要有TypeAttributes.Inte ...
- MSIL实用指南-生成if...else...语句
if...else...语句是非常重要的选择语句,它的生成一般需要ILGenerator的DefineLabel方法和MarkLabel方法,以及Brtrue_S和Br_S指令. 一.DefineLa ...
- MSIL实用指南-生成内部类
生成内部类用TypeBuilder的DefineNestedType方法,得到另一个TypeBuilder.内部类的可访问性都是TypeAttributes的“Nested”开头一些成员.实例代码:y ...
- MSIL实用指南-生成foreach语句
foreach可以迭代数组或者一个集合对象.foreach语句格式是它的生成步骤是foreach (<成员> in <集合>) <循环体> 一.声明三个变量,loc ...
- MSIL实用指南-生成for语句
for语句格式是这样的for(<初始化语句>;<条件语句>;<自增减语句>) <循环体> 它可以转换为while语句 if(<条件语句>){ ...
- MSIL实用指南-生成while语句
本篇讲解怎样生成while语句.while语句是编程语言中很重要的循环语句,它的结构是while(<表达式>) <语句或语句块> 当表达式的结果为true时就一直执行语句或语句 ...
随机推荐
- Python基础总结之第四天开始【格式化‘字符串’】(新手可相互督促)
年薪20万... 字符串格式化: 先看小案例-------: a = 'hello,my name is %s,I like %s.'%('XiaoHong','football') #在字符串中,[ ...
- hdu3416+hdu6582(最短路+最大流)
题意 hdu3416: 给一个图,边不能重复选,问有多少个最短路 hdu6582: 给一个图,问最少删除边权多少的边后,最短路长度增加 分析 边不能重复选这个条件可以想到边权为1,跑最大流,所以我们可 ...
- 初始Spring 文档 完整版
初始Spring 1.Spring官网 spring.io 01. IOC(Inverse of Control)控制反转 02. AOP(Aspect Oritend Programming)面向切 ...
- 15. Java异常处理
*:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...
- 绿色版的mysql 下载安装配置方式
解压下载好的压缩包 下载地址 mysql-5.6.26-win64 绿色版 copy 一份my-default.ini改名字为my.ini为mysql的配置文件 打开my.ini 修改配置文件 默认的 ...
- vue 初始化table数据,数据闪现的问题
使用的iview,很简单的一个table,可以扩展显示,我这里则是更改了一下,显示的也是表格,内容为明细数据. 原以为很简单的可以直接调用方法,进行数据的渲染,但是没想到,数据只是一闪而过. 百思不得 ...
- 非UI线程更新界面
package com.caterSys.Thread; import java.text.SimpleDateFormat; import java.util.Date; import org.ec ...
- 基于SpringBoot从零构建博客网站 - 集成editor.md开发发布文章功能
发布文章功能里面最重要的就是需要集成富文本编辑器,目前富文本编辑器有很多,例如ueditor,CKEditor.editor.md等.这里守望博客里面是集成的editor.md,因为editor.md ...
- python多线程与多进程及其区别
个人一直觉得对学习任何知识而言,概念是相当重要的.掌握了概念和原理,细节可以留给实践去推敲.掌握的关键在于理解,通过具体的实例和实际操作来感性的体会概念和原理可以起到很好的效果.本文通过一些具体的例子 ...
- jQuery插件之路(三)——文件上传(支持拖拽上传)
好了,这次咱一改往日的作风,就不多说废话了,哈哈.先贴上源代码地址,点击获取.然后直接进入主题啦,当然,如果你觉得我有哪里写的不对或者欠妥的地方,欢迎留言指出.在附上一些代码之前,我们还是先来了解下, ...