C# 异常处理

异常是在程序执行期间发生的意外事件。例如,

int divideByZero = 7 / 0;

以上代码会引发一个异常,因为一个数字不能被 0 整除。

异常会异常地终止程序指令的流程,我们需要处理这些异常。响应或处理异常称为异常处理


C# 异常处理块

C# 提供了内置的块来处理异常。它们是:try..catchfinally

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 块与 trycatch 块一起使用。无论是否发生异常,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 block is always getting executed
C# finally 块

从上图可以看出,finally 块在两种情况下都会执行。finally 块执行

  • trycatch 块之后 - 当异常发生时
  • 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 块之后直接执行。例如,如果我们输入92try 块中不会发生异常,我们将获得以下输出

// 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

在 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 块。

C# 通用 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 块引发的任何类型的异常。

使用两个 catch 块进行异常处理

在 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 块未处理该异常。

你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战