📜  C#中的异常处理

📅  最后修改于: 2021-05-29 19:17:26             🧑  作者: Mango

异常定义为在程序执行过程中发生的事件,该事件是程序代码无法预料的。程序不知道发生异常时要执行的动作。在这种情况下,我们将创建一个异常对象并调用异常处理程序代码。为了使程序代码不崩溃,执行异常处理程序称为异常处理。异常处理很重要,因为它可以优雅地处理不需要的事件(异常),因此程序代码对用户仍然有意义。

Keyword Definition
try Used to define a try block. This block holds the code that may throw an exception.
catch Used to define a catch block. This block catches the exception thrown by the try block.
finally Used to define the finally block. This block holds the default code.
throw Used to throw an exception manually.

让我们举一个简单的例子来了解什么是异常:

// C# program to show how 
// Exceptions occur in a program
using System;
  
class GFG {
  
    static void Main(string[] args)
    {
        // Declare an array of max index 4
        int[] arr = { 1, 2, 3, 4, 5 };
  
        // Display values of array elements
        for (int i = 0; i < arr.Length; i++) {
            Console.WriteLine(arr[i]);
        }
  
        // Try to access invalid index of array
        Console.WriteLine(arr[7]);
        // An execption is thrown upon executing
        // the above line
    }
}

运行时错误:

输出:

1
2
3
4
5

在上面给出的代码中,为5个元素定义了名为“ arr”的数组,索引从0到4。当我们尝试访问数组的第7个元素(即不存在)时,程序代码将引发异常,并且上述消息被陈列。可以使用C#的System.Exception类处理该异常。这将在下面给出的代码中进行描述。

使用try-catch块的异常处理

下面给出的代码显示了我们如何使用try-catch块处理异常。可能产生异常的代码放在try块中。在这种情况下,对第7个元素的访问将放在try块内。当执行该语句时,将生成一个异常,该异常将被catch块捕获。类型为IndexOutOfRangeException的对象用于向用户显示有关已发生的异常的消息。

句法:

try
{
  // statements that may cause an exception
}
catch( Exception obj)
{
  // handler code
}
// Exception handling of above code
// using try catch blocks
  
using System;
  
class Program : System.Exception {
    static void Main(string[] args)
    {
        // Declare an array of max index 4
        int[] arr = { 1, 2, 3, 4, 5 };
  
        // Display values of array elements
        for (int i = 0; i < arr.Length; i++) {
            Console.WriteLine(arr[i]);
        }
  
        try {
  
            // Try to access invalid index of array
            Console.WriteLine(arr[7]);
            // An execption is thrown upon executing
            // the above line
        }
        catch (IndexOutOfRangeException e) {
  
            // The Message property of the object 
            // of type IndexOutOfRangeException
            // is used to display the type of exception
            // that has occurred to the user.
            Console.WriteLine("An Exception has occurred : {0}", e.Message);
        }
    }
}

输出:

1
2
3
4
5
An Exception has occurred : Index was outside the bounds of the array.

使用多个try-catch块

在下面给出的代码中,我们尝试在try块中生成一个异常并将其捕获到多个catch块之一中。当我们不确定可能生成的异常类型时,会使用多个catch块,因此我们编写不同的块来处理遇到的任何类型的异常。
无论是否生成异常,finally块都是必须执行的代码部分。在下面给出的程序中,数组的元素显示在finally块中。

句法:

try
{
  // statements that may cause an exception
}
catch(Specific_Exception_type obj)
{
  // handler code
}
catch(Specific_Exception_type obj)
{
  // handler code
}
.
.
.
finally
{
  //default code
}
// C# Program to show use of
// multiple try catch blocks
using System;
  
class Program {
  
    static void Main(string[] args)
    {
        int[] arr = {19, 0, 75, 52};
  
        try {
  
            // Try to generate an exception
            for (int i = 0; i < arr.Length; i++) {
                Console.WriteLine(arr[i] / arr[i + 1]);
            }
        }
  
        // Catch block for invalid array access
        catch (IndexOutOfRangeException e) {
  
            Console.WriteLine("An Exception has occurred : {0}", e.Message);
        }
  
        // Catch block for attempt to divide by zero
        catch (DivideByZeroException e) {
  
            Console.WriteLine("An Exception has occurred : {0}", e.Message);
        }
  
        // Catch block for value being out of range
        catch (ArgumentOutOfRangeException e) {
  
            Console.WriteLine("An Exception has occurred : {0}", e.Message);
        }
  
        // Finally block
        // Will execute irrespective of the above catch blocks
        finally {
            for (int i = 0; i < arr.Length; i++) {
                Console.Write(" {0}", arr[i]);
            }
        }
    }
}

输出:

An Exception has occurred : Attempted to divide by zero.
 19 0 75 52

用户定义的异常

当我们要编写语言未定义的异常时,用户定义的异常很有用。例如,在锅炉房中,如果温度升高到某个阈值以上,则必须关闭热量。为了理解如何使用用户定义的异常,我们举一个除以零的示例。在这里,我们定义一个类DivByZero,该类继承自Exception,并且在分母等于零时由DivisionOperation函数调用。由于对该函数的调用可能会引发异常,也可能不会引发异常,因此将其放置在try块中。定义了一个catch块来捕获Exception类型的任何异常,并且Message属性将显示已发生的异常的类型。

// C# program to show the user defined exceptions
using System;
  
// User defined Exception class
// Child of Exception
class DivByZero : Exception {
  
    // Constructor
    public DivByZero()
    {
        Console.Write("Exception has occurred : ");
    }
}
  
class Program {
  
    // Method to perform Division
    public double DivisionOperation(double numerator,
                                 double denominator)
    {
        // throw exception when denominator
        // value is 0
        if (denominator == 0)
            throw new DivByZero();
  
        // Otherwise return the result of the division
        return numerator / denominator;
    }
  
    // Main
    static void Main(string[] args)
    {
        Program obj = new Program();
        double num = 9, den = 0, quotient;
        try {
            // Code block that may cause an exception
            quotient = obj.DivisionOperation(num, den);
            Console.WriteLine("Quotient = {0}", quotient);
        }
        // Catch block to catch the generic exception
        catch (Exception e) {
            // Message property of exception object e
            // will give the specific type of the exception
            Console.Write(e.Message);
        }
    }
}

输出:

Exception has occurred : Exception of type 'DivByZero' was thrown.