Pregunta

I am trying to learn how to debug and handle errors in C# code using VS2012 for Desktop. I am stepping-through the below code using the Step Into F11 technique.

I understand how the execution of code jumps between different parts of code. I have messages printed out to console to help me identify which step is being executed. I have split my screen so I can see which line of code I'm stepping into and the output messages in the console at the same time.

On line 70 (marked in the comments) - when the nested index is passed to the throwException() I do not understand why there is a throw keyword and what its functionality is. Why does the pointer jump to the nested finally block but then it goes back all the way to the main and throws IndexOutOfBounds exception. What does that mean? I see where the execution jump in the code but I don't understand why it just says throw. Does it mean that the exception is already handled? But how?

I read that when you throw an exception there is no need to add a break; statement because the switch statement breaks when it meets throw keyword, but I am not sure this is the right path of thinking in this example.

Please, help me understand the meaning of the throw keyword on line 70.

Thank you in advance.

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;
         }
      }
   }
}

The above code compiles and runs with no errors.

¿Fue útil?

Solución

Keyword throw can be used all by itself inside a catch clause to rethrow whatever exception has been caught by that catch block. It lets you "plug in" some execution logic in the process of handling the exception without disrupting the details of where the exception has been thrown.

In this case, you are able to log the details to console, and then re-throw the exception as if you never handled it. Note that this is different from catching an exception and wrapping it in your own, because the details of the original exception are preserved.

Otros consejos

throw; inside a catch says "I don't actually know what to do about this exception so let somebody else higher up the stack catch it (without me having modified it)."

The throw in question will re-throw the exception, such that the stack trace and other info is preserved.

Have a look at Rethrow to preserve stack details

Also from try-catch (C# Reference)

If you want to re-throw the exception currently handled by a parameter-less catch clause, use the throw statement without arguments

catch
{
    throw;
}

The throw keyword is used to re-throw caught exceptions without losing the correct stack trace. It is used to do some execution when the exception is caught (for example logging, as it is in your example).

Please see this: SO qeustion on rethrowing exceptions and this: codinghorror blogpost (please note the clarifications in the comments)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top