异常是在程序执行过程中出现的问题。C# 异常是对程序运行时发生的异常情况的一种响应,例如尝试除以零。
异常提供了一种从程序的一部分转移到另一部分的方法。C# 的异常处理基于四个关键字:try
、catch
、finally
和 throw
。
try
−
try
块标识了一个代码块,该代码块中的特定异常会被激活。它后面跟着一个或多个 catch
块。
catch
−
程序在一个地方通过异常处理器捕获异常,这个地方是你想要处理问题的地方。catch
关键字表示捕获了一个异常。
finally
−
finally
块用于执行一组无论是否抛出异常都会被执行的语句。例如,如果你打开了一个文件,不管是否抛出了异常,这个文件都必须关闭。
throw
−
当出现问题时,程序会使用 throw
关键字抛出异常。
语法
假设一个块可能会引发异常,那么可以使用 try
和 catch
关键字的组合来捕获异常。一个 try/catch
块围绕着可能会产生异常的代码。位于 try/catch
块内的代码被称为受保护代码,使用 try/catch
的语法如下:
try {
} catch( ExceptionName e1 ) {
} catch( ExceptionName e2 ) {
} catch( ExceptionName eN ) {
} finally {
}
你可以列出多个 catch
语句来捕获不同的异常类型,如果你的 try
块在不同情况下可能会引发不止一个异常的话。
C# 中的异常类
C# 异常由类来表示。C# 中的异常类主要直接或间接地从 System.Exception
类派生而来。一些从 System.Exception
类派生的异常类包括 System.ApplicationException
和 System.SystemException
类。
System.ApplicationException
类支持应用程序程序产生的异常。因此程序员定义的异常应该从此类派生。
System.SystemException
类是所有预定义系统异常的基础类。
下表提供了一些从 System.SystemException
类派生的预定义异常类:
序号 |
异常类 |
描述 |
1 |
System.IO.IOException |
处理 I/O 错误。 |
2 |
System.IndexOutOfRangeException |
处理方法引用超出范围的数组索引错误。 |
3 |
System.ArrayTypeMismatchException |
处理类型与数组类型不匹配的错误。 |
4 |
System.NullReferenceException |
处理对空对象的引用产生的错误。 |
5 |
System.DivideByZeroException |
处理除数为零的错误。 |
6 |
System.InvalidCastException |
处理类型转换期间产生的错误。 |
7 |
System.OutOfMemoryException |
处理内存不足产生的错误。 |
8 |
System.StackOverflowException |
处理栈溢出产生的错误。 |
处理异常
C# 提供了一种结构化的解决方案来处理异常的形式,即 try
和 catch
块。使用这些块可以将核心程序语句与错误处理语句分开。
这些错误处理块是通过 try
、catch
和 finally
关键字实现的。下面是一个在发生除以零的情况下抛出异常的例子:
示例代码
using System;
namespace ErrorHandlingApplication {
class DivNumbers {
int result;
DivNumbers() {
result = 0;
}
public void division(int num1, int num2) {
try {
result = num1 / num2;
} catch (DivideByZeroException e) {
Console.WriteLine("捕获到异常: {0}", e);
} finally {
Console.WriteLine("结果: {0}", result);
}
}
static void Main(string[] args) {
DivNumbers d = new DivNumbers();
d.division(25, 0);
Console.ReadKey();
}
}
}
当上述代码被编译和执行时,它产生以下结果:
捕获到异常: System.DivideByZeroException: 尝试除以零。
在 ... 处
结果: 0
创建用户定义的异常
你也可以定义自己的异常。用户定义的异常类是从 Exception
类派生出来的。下面的例子演示了这一点:
示例代码
using System;
namespace UserDefinedException {
class TestTemperature {
static void Main(string[] args) {
Temperature temp = new Temperature();
try {
temp.showTemp();
} catch(TempIsZeroException e) {
Console.WriteLine("TempIsZeroException: {0}", e.Message);
}
Console.ReadKey();
}
}
}
public class TempIsZeroException: Exception {
public TempIsZeroException(string message): base(message) {
}
}
public class Temperature {
int temperature = 0;
public void showTemp() {
if(temperature == 0) {
throw (new TempIsZeroException("发现零度温度"));
} else {
Console.WriteLine("温度: {0}", temperature);
}
}
}
当上述代码被编译和执行时,它产生以下结果:
TempIsZeroException: 发现零度温度
抛出对象
如果一个对象是直接或间接从 System.Exception
类派生的,那么你可以抛出这个对象。你可以在 catch
块中使用 throw
语句来抛出当前的对象,如下所示:
catch(Exception e) {
...
throw e;
}