C# 异常处理
异常是在程序执行期间出现的问题。C# 中的异常是对程序运行时出现的特殊情况的一种响应,比如尝试除以零。
异常提供了一种把程序控制权从某个部分转移到另一个部分的方式。C# 异常处理时建立在四个关键词之上的:try、catch、finally 和 throw。
- try:一个 try 块标识了一个将被激活的特定的异常的代码块。后跟一个或多个 catch 块。
- catch:程序通过异常处理程序捕获异常。catch 关键字表示异常的捕获。
- finally:finally 块用于执行给定的语句,不管异常是否被抛出都会执行。例如,如果您打开一个文件,不管是否出现异常文件都要被关闭。
- throw:当问题出现时,程序抛出一个异常。使用 throw 关键字来完成。
语法
假设一个块将出现异常,一个方法使用 try 和 catch 关键字捕获异常。try/catch 块内的代码为受保护的代码,使用 try/catch 语法如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<span class="hljs-keyword">try</span> { <span class="hljs-comment">// 引起异常的语句</span> } <span class="hljs-keyword">catch</span>( ExceptionName e1 ) { <span class="hljs-comment">// 错误处理代码</span> } <span class="hljs-keyword">catch</span>( ExceptionName e2 ) { <span class="hljs-comment">// 错误处理代码</span> } <span class="hljs-keyword">catch</span>( ExceptionName eN ) { <span class="hljs-comment">// 错误处理代码</span> } <span class="hljs-keyword">finally</span> { <span class="hljs-comment">// 要执行的语句</span> } |
您可以列出多个 catch 语句捕获不同类型的异常,以防 try 块在不同的情况下生成多个异常。
一、C# 中的异常类
C# 异常是使用类来表示的。C# 中的异常类主要是直接或间接地派生于 System.Exception 类。System.ApplicationException 和 System.SystemException 类是派生于 System.Exception 类的异常类。
System.ApplicationException 类支持由应用程序生成的异常。所以程序员定义的异常都应派生自该类。
System.SystemException 类是所有预定义的系统异常的基类。
下表列出了一些派生自 Sytem.SystemException 类的预定义的异常类:
异常类 | 描述 |
---|---|
System.IO.IOException | 处理 I/O 错误。 |
System.IndexOutOfRangeException | 处理当方法指向超出范围的数组索引时生成的错误。 |
System.ArrayTypeMismatchException | 处理当数组类型不匹配时生成的错误。 |
System.NullReferenceException | 处理当依从一个空对象时生成的错误。 |
System.DivideByZeroException | 处理当除以零时生成的错误。 |
System.InvalidCastException | 处理在类型转换期间生成的错误。 |
System.OutOfMemoryException | 处理空闲内存不足生成的错误。 |
System.StackOverflowException | 处理栈溢出生成的错误。 |
二、异常处理
C# 以 try 和 catch 块的形式提供了一种结构化的异常处理方案。使用这些块,把核心程序语句与错误处理语句分离开。
这些错误处理块是使用 try、catch 和 finally 关键字实现的。下面是一个当除以零时抛出异常的实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<span class="hljs-keyword">using</span> System; <span class="hljs-keyword">namespace</span> <span class="hljs-title">ErrorHandlingApplication</span> { <span class="hljs-keyword">class</span> <span class="hljs-title">DivNumbers</span> { <span class="hljs-keyword">int</span> result; DivNumbers() { result = <span class="hljs-number">0</span>; } <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">division</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> num1, <span class="hljs-keyword">int</span> num2</span>) </span>{ <span class="hljs-keyword">try</span> { result = num1 / num2; } <span class="hljs-keyword">catch</span> (DivideByZeroException e) { Console.WriteLine(<span class="hljs-string">"Exception caught: {0}"</span>, e); } <span class="hljs-keyword">finally</span> { Console.WriteLine(<span class="hljs-string">"Result: {0}"</span>, result); } } <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>(<span class="hljs-params"><span class="hljs-keyword">string</span>[] args</span>) </span>{ DivNumbers d = <span class="hljs-keyword">new</span> DivNumbers(); d.division(<span class="hljs-number">25</span>, <span class="hljs-number">0</span>); Console.ReadKey(); } } } |
当上面的代码被编译和执行时,它会产生下列结果:
1 2 3 4 |
Exception caught: System.DivideByZeroException: Attempted to divide by zero. at ... Result: <span class="hljs-number">0</span> |
三、创建用户自定义异常
您也可以定义自己的异常。用户自定义的异常类是派生自 ApplicationException 类。下面的实例演示了这点:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<span class="hljs-keyword">using</span> System; <span class="hljs-keyword">namespace</span> <span class="hljs-title">UserDefinedException</span> { <span class="hljs-keyword">class</span> <span class="hljs-title">TestTemperature</span> { <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>(<span class="hljs-params"><span class="hljs-keyword">string</span>[] args</span>) </span>{ Temperature temp = <span class="hljs-keyword">new</span> Temperature(); <span class="hljs-keyword">try</span> { temp.showTemp(); } <span class="hljs-keyword">catch</span>(TempIsZeroException e) { Console.WriteLine(<span class="hljs-string">"TempIsZeroException: {0}"</span>, e.Message); } Console.ReadKey(); } } } <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">TempIsZeroException</span>: <span class="hljs-title">ApplicationException</span> { <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">TempIsZeroException</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> message</span>): <span class="hljs-title">base</span>(<span class="hljs-params">message</span>) </span>{ } } <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Temperature</span> { <span class="hljs-keyword">int</span> temperature = <span class="hljs-number">0</span>; <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">showTemp</span>() </span>{ <span class="hljs-keyword">if</span>(temperature == <span class="hljs-number">0</span>) { <span class="hljs-keyword">throw</span> (<span class="hljs-keyword">new</span> TempIsZeroException(<span class="hljs-string">"Zero Temperature found"</span>)); } <span class="hljs-keyword">else</span> { Console.WriteLine(<span class="hljs-string">"Temperature: {0}"</span>, temperature); } } } |
当上面的代码被编译和执行时,它会产生下列结果:
1 2 |
TempIsZeroException: Zero Temperature found |
四、抛出对象
如果异常是直接或间接派生自 System.Exception 类,您可以抛出一个对象。您可以在 catch 块中使用 throw 语句来抛出当前的对象,如下所示:
1 2 3 4 5 |
Catch(Exception e) { ... Throw e } |