本篇讲解怎么生成异常。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. 在父页面用Iframe加载子页面时,将父页面的title替换成子页面title

    报告管理

  2. myeclipse中更改默认jdk版本出错( Target is not a JDK root. System library was not found)

    原因是我的本地jdk版本是9.0,将jdk版本更改至8.0即可导入成功. jdk9.0导入myeclipse中去会有此类问题的发生,因此没有必要使用最新的jdk版本.

  3. 动态规划_Apple Catching_POJ-2385

    It and ) in his field, each full of apples. Bessie cannot reach the apples when they are on the tree ...

  4. 【Spring】The matching wildcard is strict……

    applicationContext.xml 文件抛出了这个异常信息. 解决方法: 需要在 namespace 后加上对应的 schemaLocation,如下所示: <?xml version ...

  5. Android开发进阶——自定义View的使用及其原理探索

    在Android开发中,系统提供给我们的UI控件是有限的,当我们需要使用一些特殊的控件的时候,只靠系统提供的控件,可能无法达到我们想要的效果,这时,就需要我们自定义一些控件,来完成我们想要的效果了.下 ...

  6. Java编程思想之十七 容器深入研究

    17.1 完整的容器分类方法 17.2 填充容器 import java.util.*; class StringAddress { private String s; public StringAd ...

  7. 一道看似简单的go程序的深入分析

    先上代码: func main() { var a [10]int for i := 0; i < 10; i++ { go func(i int) { for { a[i]++ } }(i) ...

  8. (14)ASP.NET Core 中的日志记录

    1.前言 ASP.NET Core支持适用于各种内置和第三方日志记录提供应用程序的日志记录API.本文介绍了如何将日志记录API与内置提供应用程序一起使用. 2.添加日志提供程序 日志记录提供应用程序 ...

  9. 【Java例题】5.3 线性表的使用

    3.线性表的使用.使用ArrayList模拟一个一维整数数组.数据由Random类随机产生.进行对输入的一个整数进行顺序查找.并进行冒泡排序. package chapter6; import jav ...

  10. 通过jmeter发送webservice接口请求

    1.webservice接口地址:http://ip:port/...?wsdl 2.接口数据类型:<cuxGmiChukuRmaTrxV><salesrepId xmlns:xsi ...