本篇讲解怎么生成异常。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实用指南-生成异常处理的更多相关文章

  1. MSIL实用指南-生成索引器

    MSIL实用指南-生成索引器 索引器是一种特殊的属性,它有参数的,也有get和set方法,属性名称一般是"Item",并且方法名称一般名称是"get_Item" ...

  2. MSIL实用指南-生成属性

    本篇讲解怎么生成属性,包括get和set方法. 第一步,生成一个字段生成字段用TypeBuilder.DefineField方法.实例代码: FieldBuilder customerNameBldr ...

  3. MSIL实用指南-生成构造函数

    本篇讲解生成构造函数的一些知识,包括创建实例构造函数.静态构造函数.调用父类构造函数. 生成构造函数的方法生成构造函数的方法是TypeBuilder.DefineConstructor(MethodA ...

  4. MSIL实用指南-生成接口

    本篇讲解怎么样生成接口,即interface. 一.创建类型创建一个接口类型依旧用ModuleBuilder的DefineType方法,但是它的第二个参数必须要有TypeAttributes.Inte ...

  5. MSIL实用指南-生成if...else...语句

    if...else...语句是非常重要的选择语句,它的生成一般需要ILGenerator的DefineLabel方法和MarkLabel方法,以及Brtrue_S和Br_S指令. 一.DefineLa ...

  6. MSIL实用指南-生成内部类

    生成内部类用TypeBuilder的DefineNestedType方法,得到另一个TypeBuilder.内部类的可访问性都是TypeAttributes的“Nested”开头一些成员.实例代码:y ...

  7. MSIL实用指南-生成foreach语句

    foreach可以迭代数组或者一个集合对象.foreach语句格式是它的生成步骤是foreach (<成员> in <集合>) <循环体> 一.声明三个变量,loc ...

  8. MSIL实用指南-生成for语句

    for语句格式是这样的for(<初始化语句>;<条件语句>;<自增减语句>) <循环体> 它可以转换为while语句 if(<条件语句>){ ...

  9. MSIL实用指南-生成while语句

    本篇讲解怎样生成while语句.while语句是编程语言中很重要的循环语句,它的结构是while(<表达式>) <语句或语句块> 当表达式的结果为true时就一直执行语句或语句 ...

随机推荐

  1. 《VR入门系列教程》之17---发布第一个应用

    发布运行     Unity可以支持多种目标平台的发布,包括:桌面端.Web端.移动端.游戏主机端.     发布运行之前的Cubes场景至桌面端,我们先选择File->Build Settin ...

  2. File文件类

    目录 File文件类 File类的构造方法 File类的创建功能 File类的重命名 File类的删除功能 File类的判断功能 File类的获取功能 文件名称过滤器 File文件类 File:文件和 ...

  3. layui上传Excel更新数据并下载

    前言: 最近做项目遇到了一个需求,上传Excel获取数据更新Excel文档,并直接返回更新完的Excel到前端下载:其实需求并没有什么问题,关键是前端用到的是layui上传组件(layui.uploa ...

  4. bean的创建(五)第三部分 bean工厂方法参数的解析

    准备好一系列参数之后,开始参数类型的转换,方法参数的对应. ConstructorResolver.createArgumentArray private ArgumentsHolder create ...

  5. Promise异步编程解决方案

    Promise是ES6中新增的异步编程解决方案,体现在代码中它是一个对象,可以通过 Promise 构造函数来实例化. 其最基本的使用 new Promise(function(resolve,rej ...

  6. STL 大法好

    #include <vector>  1.支持随机访问,但不支持在任意位置O(1)插入:    2.定义:  ```cpp      vector<int> a;  ```  ...

  7. 在 dotnet core (C#)下的颜色渐变

    直接使用等比例抽样算法,连同透明度一起计算. public IList<Color> ShadeColors(Color c1, Color c2, int resultCount) { ...

  8. Wtm携手LayUI -- .netcore 开源生态我们是认真的!

    经过WTM团队和LayUI团队多次深入协商,双方于2019年7月29日在北京中国国际展览中心正式达成战略合作意向, 双方签署了战略合作框架协议,LayUI团队承诺使用WTM框架的任何项目都可以免费使用 ...

  9. [转载]线程池ThreadPoolExecutor使用简介

    一.简介 线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为: ThreadPoolExecutor(int corePoolSize, int ...

  10. Java并发编程实战笔记—— 并发编程1

    1.如何创建并运行java线程 创建一个线程可以继承java的Thread类,或者实现Runnabe接口. public class thread { static class MyThread1 e ...