C# try catch finally的用法(非常详细)
在 C# 中,有时也可以将程序错误(error)称为程序异常(exception),相信每一位写程序的人都会常常碰上程序异常。
过去碰上程序异常,程序终止执行的同时会出现错误信息,错误信息内容通常显示 Unhandled exception,然后列出异常报告。C# 提供功能可以让我们捕捉异常并撰写异常处理程序,当发生的异常被我们捕捉后会去执行异常处理程序,然后程序可以继续执行。
以一个除数为 0 的错误为例开始说明:
其实对于上述程序而言,若是程序可以执行到第 7 行,是可以正常得到执行结果的,可是程序第 6 行已经造成程序终止了,所以无法执行第 7 行。
例如:
当程序执行第 14 行时,会将参数 (3, 0) 带入 Division() 函数,由于执行 try 的指令“x / y”产生了除数为 0 的“DivideByZeroException”异常,这时 C# 会找寻是否有处理这类异常的 catch(DivideByZeroException) 存在,如果有就表示此异常被捕提,就去执行相关的错误处理程序。
此例中是执行第 9~10 行,输出“除数不可为0”的错误,同时因为 Division() 函数是 double?,所以必须要有回传值,此例回传 null。函数返回后打印出结果 null,None 是一个对象表示结果不存在,所以输出空白行,最后返回程序第 15 行,继续执行相关指令。
从上述可以看到,程序增加了 try-catch 后,若是异常被捕提,出现的异常信息就比较友善了,同时不会有程序中断的情况发生。
特别需留意的是在 try catch 的使用中,如果在 try 后面的指令产生异常时,这个异常不是我们设计的 catch 异常对象,表示异常没被捕提到,这时程序依旧会像文章开头的实例程序一样,直接出现错误信息,然后程序终止。
例如:
下表罗列了 C# 程序中常见的异常对象:
在 try catch 的使用中,可以设计多个 catch 捕捉多种异常,此时语法如下:
例如:
例如:
例如:
过去碰上程序异常,程序终止执行的同时会出现错误信息,错误信息内容通常显示 Unhandled exception,然后列出异常报告。C# 提供功能可以让我们捕捉异常并撰写异常处理程序,当发生的异常被我们捕捉后会去执行异常处理程序,然后程序可以继续执行。
以一个除数为 0 的错误为例开始说明:
double? Division(int x, int y) { return x / y; } Console.WriteLine(Division(9, 3)); // 输出 9 / 3 Console.WriteLine(Division(3, 0)); // 输出 3 / 0 Console.WriteLine(Division(4, 2)); // 输出 4 / 2执行结果为:
3
Unhandled exception. System.DivideByZeroException: Attempted to divide by zero.
其实对于上述程序而言,若是程序可以执行到第 7 行,是可以正常得到执行结果的,可是程序第 6 行已经造成程序终止了,所以无法执行第 7 行。
C# try catch指令
接下来讲解如何捕捉异常并设计异常处理程序,发生的异常被捕捉后程序会执行异常处理程序,然后跳开异常位置,再继续往下执行。这时要使用 try-catch 指令,它的语法格式如下:try { 系列工作指令 // 预先设想可能引发错误异常的指令 } catch ( ExceptionName ) { 异常处理程序 // 通常是指异常原因方便修正 }上述语句会执行 try 下面的区块指令,如果正常则跳离 catch 部分,如果指令有错误异常,则检查此异常是否为 ExceptionName 所指的错误,如果是则代表异常被捕提了,这时会执行 catch 下面区块的异常处理指令。
例如:
double? Division(int x, int y) { try { return x / y; } catch (DivideByZeroException) { Console.WriteLine("除数不可为 0"); return null; } } Console.WriteLine(Division(9, 3)); // 输出 9 / 3 Console.WriteLine(Division(3, 0)); // 输出 3 / 0 Console.WriteLine(Division(4, 2)); // 输出 4 / 2执行结果为:
3
除数不可为 0
2
当程序执行第 14 行时,会将参数 (3, 0) 带入 Division() 函数,由于执行 try 的指令“x / y”产生了除数为 0 的“DivideByZeroException”异常,这时 C# 会找寻是否有处理这类异常的 catch(DivideByZeroException) 存在,如果有就表示此异常被捕提,就去执行相关的错误处理程序。
此例中是执行第 9~10 行,输出“除数不可为0”的错误,同时因为 Division() 函数是 double?,所以必须要有回传值,此例回传 null。函数返回后打印出结果 null,None 是一个对象表示结果不存在,所以输出空白行,最后返回程序第 15 行,继续执行相关指令。
从上述可以看到,程序增加了 try-catch 后,若是异常被捕提,出现的异常信息就比较友善了,同时不会有程序中断的情况发生。
特别需留意的是在 try catch 的使用中,如果在 try 后面的指令产生异常时,这个异常不是我们设计的 catch 异常对象,表示异常没被捕提到,这时程序依旧会像文章开头的实例程序一样,直接出现错误信息,然后程序终止。
C# try catch finally的用法
C# 在 try catch 中又增加了 finally 区块,不论是否捕捉到错误 C# 都会执行此 finally 区块的内容。try { 系列工作指令 // 预先设想可能引发错误异常的指令 } catch ( ExceptionName ) { 异常处理程序 // 通常是指异常原因方便修正 } finally { 一定要执行的内容 }
例如:
double? Division(int x, int y) { try { return x / y; } catch (DivideByZeroException) { Console.WriteLine("除数不可为 0"); return null; } finally { Console.WriteLine("Division()测试结束"); } } Console.WriteLine(Division(9, 3)); // 输出 9 / 3 Console.WriteLine(Division(3, 0)); // 输出 3 / 0 Console.WriteLine(Division(4, 2)); // 输出 4 / 2执行结果为:
Division()测试结束
3
除数不可为 0
Division()测试结束
Division()测试结束
2
C#设计多组异常处理程序
在程序设计时,有太多不可预期的异常发生,所以我们需要知道设计程序时需要同时设计多个异常处理程序。下表罗列了 C# 程序中常见的异常对象:
异常对象名称 | 说明 |
---|---|
ArgumentException | 非空参数传递给方法 |
ArgumentNullException | 空参数传递给方法 |
ArgumentOutOfRangeException | 参数超出有效范围 |
DivideByZeroException | 整数除以 0 |
FileNotFoundException | 文件不存在 |
FormatException | 格式错误,如字符串转整数格式错误 |
IndexOutOfRangeException | 索引超出范围 |
InvalidOperationException | 对象状态是无效的 |
KeyNotFoundException | 键不存在 |
NotSupportedException | 方法或操作目前没有支持 |
NullReferenceException | 程序存取空对象 |
OverflowException | 代数运算或转换发生溢位 |
OutOfMemoryException | 内存不足 |
StackOverflowException | 栈溢出 |
TimeoutException | 配置操作的时间区段结束 |
在 try catch 的使用中,可以设计多个 catch 捕捉多种异常,此时语法如下:
try { 系列工作指令 // 预先设想可能引发错误异常的指令 } catch ( ExceptionName e1 ) { Console.WriteLine(e1.Message) // 输出系统异常说明文字 } catch ( ExceptionName e2 ) { Console.WriteLine(e2.Message) // 输出系统异常说明文字 }
例如:
double? Division(int x, int y) { try { return x / y; } catch (DivideByZeroException e1) { Console.WriteLine(e1.Message); return null; } catch (ArgumentOutOfRangeException e2) { Console.WriteLine(e2.Message); return null; } } Console.WriteLine(Division(9, 3)); // 输出 9 / 3 Console.WriteLine(Division(3, 0)); // 输出 3 / 0 Console.WriteLine(Division(4, 2)); // 输出 4 / 2执行结果为:
3
Attempted to divide by zero.
2
C#捕捉所有异常
程序设计时的许多异常是我们不可预期的,很难一次设想周到,C# 提供语法让我们可以一次捕捉所有异常,此时 try catch 语法如下:try { 系列工作指令 // 预先设想可能引发错误异常的指令 } catch { 异常处理程序 // 输出系统异常说明文字 }上述 catch 右边没有任何异常对象名称,表示如果发生异常会自动执行此区块指令。
例如:
double? Division(int x, int y) { try { return x / y; } catch { Console.WriteLine("异常发生"); return null; } } Console.WriteLine(Division(9, 3)); // 输出 9 / 3 Console.WriteLine(Division(3, 0)); // 输出 3 / 0 Console.WriteLine(Division(4, 2)); // 输出 4 / 2执行结果为:
3
异常发生
2
C# Exception
在 try catch 语法中,如果在 catch 右边的小括号内放“Exception e”,也可以捕捉所有的异常,此时语法如下:try { 系列工作指令 // 预先设想可能引发错误异常的指令 } catch (Exception e) { 异常处理程序 // 输出系统异常说明文字 }
例如:
double? Division(int x, int y) { try { return x / y; } catch (Exception e) { Console.WriteLine(e.Message); return null; } } Console.WriteLine(Division(9, 3)); // 输出 9 / 3 Console.WriteLine(Division(3, 0)); // 输出 3 / 0 Console.WriteLine(Division(4, 2)); // 输出 4 / 2执行结果为:
3
Attempted to divide by zero.
2