异常是在程序执行期间发生的意外事件。例如,
int divideByZero = 7 / 0;
以上代码会引发一个异常,因为一个数字不能被 0 整除。
异常会异常地终止程序指令的流程,我们需要处理这些异常。响应或处理异常称为异常处理。
C# 异常处理块
C# 提供了内置的块来处理异常。它们是:try..catch
和 finally
。
try...catch 块
try..catch
块用于在 C# 中处理异常。这是 try...catch
块的语法
try
{
// code that may raise an exception
}
catch (Exception e)
{
// code that handles the exception
}
在这里,我们将可能生成异常的代码放在 try
块中。然后 try
块将异常抛出到处理已引发异常的 catch
块。例如,
try
{
int num = 0;
// code that may raise an exception
int divideByZero = 7 / num;
}
catch (Exception e)
{
Console.WriteLine("Exception has occurred");
}
在这里,我们正尝试将一个数字除以零。在这种情况下,会发生异常。因此,我们将此代码包含在 try
块中。catch
块会通知用户发生的异常。
示例:使用 try...catch 进行异常处理
using System;
class Program
{
static void Main()
{
string[] colors = { "Red", "Blue", "Green" };
try
{
// code that may raise an exception
Console.WriteLine(colors[5]);
}
catch (IndexOutOfRangeException e)
{
Console.WriteLine("An exception occurred: " + e.Message);
}
}
}
输出
An exception occurred: Index was outside the bounds of the array.
在上面的示例中,请注意代码,
Console.WriteLine(colors[5]);
由于 colors
数组在索引5处没有元素,因此上述代码会引发异常。因此,我们将此代码包含在 try
块中。
当程序遇到此代码时,会发生 IndexOutOfRangeException
。然后,异常被 catch
块捕获,并执行 catch
块内的代码。
请注意以下代码,
catch (IndexOutOfRangeException e)
{
Console.WriteLine("An exception occurred: " + e.Message);
}
这里,catch
接收 IndexOutOfRangeException
类的实例。在块内,我们使用了该类的 Message
属性来显示消息。
注意: 如果您想了解有关 Exception
类方法和属性的更多信息,请访问此处。
try...catch...finally 块
我们也可以将 finally
块与 try
和 catch
块一起使用。无论是否发生异常,finally
块始终被执行。
try...catch...finally
块的语法是
try
{
// code that may raise an exception
}
catch (Exception e)
{
// code that handles the exception
}
finally
{
// this code is always executed
}

从上图可以看出,finally
块在两种情况下都会执行。finally
块执行
- 在
try
和catch
块之后 - 当异常发生时 - 在
try
块之后 - 当未发生异常时
try..catch..finally
块可以一起用于处理异常。
现在让我们看一个使用 try...catch...finally
进行异常处理的示例。
示例:使用 try...catch...finally 块进行异常处理
using System;
public class Program
{
static void Main()
{
// take first int input from user
Console.WriteLine("Enter first number:");
int firstNumber = int.Parse(Console.ReadLine());
// take second int input from user
Console.WriteLine("Enter second number:");
int secondNumber = int.Parse(Console.ReadLine());
try
{
// code that may raise raise an exception
int divisionResult = firstNumber / secondNumber;
Console.WriteLine("Division of two numbers is: " + divisionResult);
}
// this catch block gets executed only when an exception is raised
catch (Exception e)
{
Console.WriteLine("An exception occurred: " + e.Message);
}
finally
{
// this code is always executed whether of exception occurred or not
Console.WriteLine("Sum of two numbers is: " + (firstNumber + secondNumber));
}
}
}
输出
Enter first number: 8 Enter second number: 0 An exception occurred: Attempted to divide by zero. Sum of two numbers is: 8
在上面的示例中,我们尝试使用 try...catch...finally
对两个 int
输入值执行除法和加法运算。
请注意以下代码,
try
{
// code that may raise raise an exception
int divisionResult = firstNumber / secondNumber;
}
在这里,我们将执行除法运算的代码包含在 try
中,因为此代码可能会引发 DivideByZeroException
异常。
此程序有两种情况
情况 I - 当 try
中发生异常时,将执行 catch
块,然后执行 finally
块。
情况 II - 如果 try
块中未发生异常,则 finally
块将在 try
块之后直接执行。例如,如果我们输入9和2,try
块中不会发生异常,我们将获得以下输出
// Output when exception doesn't occur
Enter first number:
9
Enter second number:
2
Division of two numbers is: 4
Sum of two numbers is: 11
常见问题
在 C# 中,另一个 try...catch
块内的 try...catch
块称为嵌套 try...catch
。例如,
using System;
class Program
{
static void Main()
{
int divisor = 0;
try
{
// nested try block
try
{
int divideByZero = 6 / divisor;
}
// inner catch block
catch (IndexOutOfRangeException e)
{
Console.WriteLine("Inner catch is executed. " + e.Message);
}
}
// outer catch block
catch (DivideByZeroException e)
{
Console.WriteLine("Outer catch block is executed. " + e.Message);
}
}
}
输出
Outer catch block is executed. Attempted to divide by zero.
在上面的示例中,我们在另一个 try-catch 块中使用了 try-catch 块。
当引发的异常类型为 IndexOutOfRangeException
时,内部 catch
块将执行。但是,在我们的程序中,外部 try
块中会引发 DivideByZeroException
,因此将执行外部 catch
块。
不带异常类的 catch
块称为通用 catch
块。例如,
using System;
class Program
{
static void Main()
{
int[] numbers = { 1, 2, 3 };
try
{
// access element present at 5th index position
Console.WriteLine(numbers[5]);
}
// generic catch block
catch
{
Console.WriteLine("Some exception occurred");
}
}
}
输出
Some exception occurred
在这里,我们已将通用 catch
块与 try
块一起使用。
注意: 通用 catch
块可以捕获和处理 try
块引发的任何类型的异常。
在 C# 中,我们可以使用多个 catch
块来处理异常。如果非通用的 catch
块未处理异常,则会执行通用的 catch
块。例如,
using System;
class Program
{
static void Main()
{
int[] numbers = { 1, 0, 3, 4 };
try
{
// code that may raise an exception
int divide = numbers[2] / numbers[1];
}
// if IndexOutofRangeException occurs, the following block is executed
catch (IndexOutOfRangeException e)
{
Console.WriteLine(e.Message);
}
// if the above catch block doesn't handle the exception,
// this block is executed
catch(Exception e)
{
Console.WriteLine("Some exception occurred");
}
}
}
输出
Some exception occurred
在这里,在 try
块内部,未引发 IndexOutofRangeException
异常,因此相应的 catch 块未处理该异常。