This article has been excerpted from book "The Complete Visual C# Programmer's Guide" from the Authors of C# Corner.
Whenever an exception occurs in a try block, the corresponding catch blocks are checked to see if they can catch the exception. If no matching exception is found even if a finally block is executed the exception is propagated to a higher-level try block. This process repeats until the exception is caught but if it is not caught, the program execution comes to an end. In other words, if the top of the call stack is reached without finding a catch block handling the exception, the default exception handler handles it and then the application terminates. If an exception is thrown from inside a catch clause when any finally block is present the finally block is executed, and the exception is propagated to higher-level exceptions. Similarly, if an exception is thrown from within a finally block, this exception is propagated to a higher-level try clause.
Listing 7.12 demonstrates propagation of exceptions.
Listing 7.12: Exception12.cs
using System;
using System.Text;
public class TestPropagation
{
public static void Main()
{
try //3
{
try //2
{
try //1
{
throw new ArgumentException();
}
catch (NullReferenceException e) //1
{
Console.WriteLine("Inside catch 1");
}
finally //1
{
Console.WriteLine("Inside finally 1");
} //1
}
catch (NullReferenceException e)//2
{
Console.WriteLine("Inside catch 2");
}
finally //2
{
Console.WriteLine("Inside finally 2");
} //2
}
catch (Exception e) //3
{
//try catching some other Exception instead
//of general Exception and ArgumentException
//Program would throw unhandled System.ArgumentException: value
//does not fall within the expected range
Console.WriteLine("Inside catch 3");
}
finally //3
{
Console.WriteLine("Inside finally 3");
}//3
Console.ReadLine();
}
}
The output of the program in Listing 7.12 is shown in Figure 7.8.
Figure 7.8: Output of Listing 7.12
Let's explain Listing 7.12 step by step. Let's start with try 1:
try //1
{
throw new ArgumentException();
}
catch(NullReferenceException e) //1
{
Console.WriteLine("Inside catch 1");
}
finally //1
{
Console.WriteLine("Inside finally 1");
} //1
In the try block above, we throw a new ArgumentException, and the catch statement only checks NullReferenceException. Therefore, we are not able to catch ArgumentException. Because of that, the first thing to display in the console is the line Inside finally 1.
catch(NullReferenceException e)//2
{
Console.WriteLine("Inside catch 2");
}
finally //2
{
Console.WriteLine("Inside finally 2");
} //2
In the second catch statement, we again check the NullReferenceException. However, we already know that we throw ArgumentException in the first try code block. Therefore, we are again not able to catch the ArgumentException. Because of that, the console will display Inside finally 2.
catch(Exception e) //3
{
Console.WriteLine("Inside catch 3");
}
finally//3
{
Console.WriteLine("Inside finally 3");
}//3
At last, in the third catch statement, we check the exception. Therefore, we are able to catch the ArgumentException because Exception is the base class for ArgumentException. The next thing to display in the console is Inside catch 3 and then Inside finally 3.
Conclusion
Hope this article would have helped you in understanding Propagation of Exceptions in C#. See other articles on the website on .NET and C#.
|
The Complete Visual C# Programmer's Guide covers most of the major components that make up C# and the .net environment. The book is geared toward the intermediate programmer, but contains enough material to satisfy the advanced developer. |