Reputation:
I couldn't find any Microsoft official resource that shows how code below the finally block execute, the only information in regards to it is the book CLR via C#, the author says:
Code below the finally block executes if no exception is thrown within the try block or if a catch block catches the exception and doesn't throw or re-throw an exception.
Let's say we have the following code:
class Program {
static void Main(string[] args) {
SomeMethod1();
Console.ReadLine();
}
static void SomeMethod1() {
try {
SomeMethod2();
}
finally {
Console.WriteLine("SomeMethod1 finally");
}
Console.WriteLine("SomeMethod1 last");
}
static void SomeMethod2() {
try {
SomeMethod3();
}
catch (DivideByZeroException e) {
Console.WriteLine("SomeMethod2 caught");
}
finally {
Console.WriteLine("SomeMethod2 finally");
}
Console.WriteLine("SomeMethod2 last");
}
static void SomeMethod3() {
try {
SomeMethod4();
}
finally {
Console.WriteLine("SomeMethod3 finally");
}
Console.WriteLine("SomeMethod3 last");
}
static void SomeMethod4() {
try {
Int32 i = 0;
var c = 3 / i;
}
finally {
Console.WriteLine("SomeMethod4 finally");
}
Console.WriteLine("SomeMethod4 last");
}
}
and the output is:
SomeMethod4 finally
SomeMethod3 finally
SomeMethod2 caught
SomeMethod2 finally
SomeMethod2 last
SomeMethod1 finally
SomeMethod1 last
You can see that "SomeMethod4 last" and "SomeMethod3 last" doesn't get printed.
"SomeMethod4 last" doesn't get printed is easy to understand as SomeMethod4
throw an exception and there is no catch block to catch the exception, so it doesn't meet the requirement that specified by the author, fair enough.
But why "SomeMethod3 last" doesn't get printed? there is no exception thrown at SomeMethod3
, just like SomeMethod1
, so why "SomeMethod1 last" get printed while "SomeMethod3 last" doesn't? Is any Microsoft official resource that explain the mechanics of it?
Upvotes: 0
Views: 72
Reputation: 574
When the exception is thrown in SomeMethod4
, it is flowing up to the calling method which is SomeMethod3
. Think of it as if SomeMethod4
was actually inline inside SomeMethod3
like this.
static void SomeMethod3()
{
try
{
try
{
Int32 i = 0;
var c = 3 / i;
}
finally
{
Console.WriteLine("SomeMethod4 finally");
}
Console.WriteLine("SomeMethod4 last");
}
finally
{
Console.WriteLine("SomeMethod3 finally");
}
Console.WriteLine("SomeMethod3 last");
}
The reason SomeMethod2
Last is being run is because it is the part that actually catches the exception.
If you add a catch to SomeMethod3
, you will see that SomeMethod3 Last
gets printed as well.
Exceptions break the flow of the application, and basically don't stop going back up the call stack until it reaches a catch statement. Technically the exception is being thrown inside SomeMethod1
, but its being caught in SomeMethod2
which means the exception never reaches SomeMethod1
.
Upvotes: 0