在 C# 错误处理练习中,throw 关键字负责什么

本文关键字:关键字 throw 什么 错误 处理 练习 | 更新日期: 2023-09-27 18:34:09

我正在尝试学习如何使用VS2012桌面版调试和处理C#代码中的错误。我正在使用单步执行F11 技术逐步完成以下代码。

我了解代码的执行如何在代码的不同部分之间跳转。我已将消息打印到控制台,以帮助我确定正在执行的步骤。我已经拆分了屏幕,以便我可以同时看到我正在步入哪一行代码以及控制台中的输出消息。

在第 70 行(在注释中标记(- 当nested index传递给throwException()时,我不明白为什么有一个 throw 关键字及其功能。为什么指针跳到嵌套的最终块,但随后它一直回到主块并抛出IndexOutOfBounds异常。那是什么意思?我看到代码中的执行跳跃位置,但我不明白为什么它只是说throw.这是否意味着异常已处理?但是怎么做呢?

我读到当您throw异常时,无需添加 break; 语句,因为 switch 语句在遇到关键字时会中断throw但我不确定这是这个例子中正确的思维方式。

请帮助我理解第 70 行中 throw 关键字的含义。

提前谢谢你。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ch07Ex02
{
   class Program
   {
      static string[] eTypes = { "none", "simple", "index", "nested index" };
      static void Main(string[] args)
      {
         foreach (string eType in eTypes)
         {
            try
            {
               Console.WriteLine("Main() try block reached.");        // Line 19
               Console.WriteLine("ThrowException('"{0}'") called.", eType);
               ThrowException(eType);
               Console.WriteLine("Main() try block continues.");      // Line 22
            }
            catch (System.IndexOutOfRangeException e)                 // Line 24
            {
               Console.WriteLine("Main() System.IndexOutOfRangeException catch"
                                 + " block reached. Message:'n'"{0}'"",
                                 e.Message);
            }
            catch                                                     // Line 30
            {
               Console.WriteLine("Main() general catch block reached.");
            }
            finally
            {
               Console.WriteLine("Main() finally block reached.");
            }
            Console.WriteLine();
         }
         Console.ReadKey();
      }
      static void ThrowException(string exceptionType)
      {
         Console.WriteLine("ThrowException('"{0}'") reached.", exceptionType);
         switch (exceptionType)
         {
            case "none":
               Console.WriteLine("Not throwing an exception.");
               break;                                               // Line 50
            case "simple":
               Console.WriteLine("Throwing System.Exception.");
               throw new System.Exception();                        // Line 53
            case "index":
               Console.WriteLine("Throwing System.IndexOutOfRangeException.");
               eTypes[4] = "error";                                 // Line 56
               break;
            case "nested index":
               try                                                  // Line 59
               {
                  Console.WriteLine("ThrowException('"nested index'") " +
                                    "try block reached.");
                  Console.WriteLine("ThrowException('"index'") called.");
                  ThrowException("index");                          // Line 64
               }
               catch                                                // Line 66
               {
                  Console.WriteLine("ThrowException('"nested index'") general"
                                    + " catch block reached.");
                  throw;                                            // Line 70 
               }
               finally
               {
                  Console.WriteLine("ThrowException('"nested index'") finally"
                                    + " block reached.");
               }
               break;
         }
      }
   }
}

上面的代码编译和运行没有错误。

在 C# 错误处理练习中,throw 关键字负责什么

关键字

throw 可以在 catch 子句中单独使用,以重新抛出该catch块捕获的任何异常。它允许您在处理异常的过程中"插入"一些执行逻辑,而不会中断引发异常的详细信息。

在这种情况下,您可以将详细信息记录到控制台,然后重新引发异常,就像您从未处理过它一样。请注意,这与捕获异常并将其包装在您自己的异常中不同,因为原始异常的详细信息会保留。

catch throw; 说:"我实际上不知道如何处理这个异常,所以让堆栈上层的其他人捕获它(没有我修改它(。

有问题的抛出将重新引发异常,以便保留堆栈跟踪和其他信息。

查看重新抛出以保留堆栈详细信息

也来自 try-catch(C# 参考(

如果要重新引发当前由 无参数 catch 子句,使用不带参数的 throw 语句

catch
{
    throw;
}

throw 关键字用于重新引发捕获的异常,而不会丢失正确的堆栈跟踪。它用于在捕获异常时执行一些执行(例如,日志记录,如示例中所示(。

请看这个: 关于重新抛出异常的 SO 问题和这个: 编码恐怖博客文章 (请注意评论中的澄清(