Skip to content
Theory · Exceptions · lesson 4 of 9

The finally block

When you leave the kitchen, turn off the stove, whatever happens. You may have finished cooking, been called to the phone or run out at the fire alarm. Either way, the stove goes off on every way out of the kitchen.

In a program, you can break this rule without noticing. Look at what happens to the stove when an exception occurs in try:

C#
Console.WriteLine("Stove on"); // Stove on
try
{
    int minutes = int.Parse("x");
    Console.WriteLine("Cooking for " + minutes);
    Console.WriteLine("Stove off");
}
catch (FormatException)
{
    Console.WriteLine("Not a number"); // Not a number
}

int.Parse("x") throws an exception, and execution jumps straight to catch. The two lines below are skipped, and Stove off is not printed: the stove was left on.

You could move Stove off after the try and catch blocks. That would help here, but not always. A method may leave early through return, and an exception of another class goes right past the catch. Then the line after the blocks does not run again.

A third block: finally

For such a rule, C# has a third block. A finally block goes after catch or right after try, and it always runs when execution leaves try:

C#
Console.WriteLine("Stove on"); // Stove on
try
{
    int minutes = int.Parse("x");
    Console.WriteLine("Cooking for " + minutes);
}
catch (FormatException)
{
    Console.WriteLine("Not a number"); // Not a number
}
finally
{
    Console.WriteLine("Stove off"); // Stove off
}

Let's go through the program step by step:

  1. Stove on is printed.
  2. int.Parse("x") throws a FormatException, and the rest of try is skipped.
  3. catch prints Not a number.
  4. finally prints Stove off.

If you replace "x" with "5", there is no exception. The program prints Stove on, Cooking for 5 and Stove off: finally runs this time too.

After return and an exception

You can also leave try early: through return, or through an exception the method does not catch itself. finally runs then as well, right before the method is left.

Interviewers like to ask: "Does finally run if try has a return?" The answer is yes. finally is skipped only when the program ends at once, as with the StackOverflowException from the methods theme.

In the program below, the method Read leaves try twice: the first time through return, the second through an exception. Press "Next step" and watch when Stove off is printed.

LiveWhen finally runsstep 1 of 8 · frames: 1

Main calls Read("5") and waits for a number to print.

The stack of frames shows which call is running now

The program prints Stove off twice, both times before execution returns to Main. Let's look at both ways out.

Leaving through return

return int.Parse(text); first computes the number 5 and remembers it. Then finally runs, and only after that does the method return 5. That is why Stove off is printed before Main prints 5.

Leaving through an exception

For "x", the exception is thrown inside the try of Read. Read has no catch of its own, so the exception goes on to Main, but finally runs on the way. Only then does the catch in Main print Caught.

Here the stove analogy falls short. After turning off the stove, you can still change your mind and stay in the kitchen. A finally block does not cancel the exit and does not catch the exception: after it, Read still returns 5 or passes the exception on.

Common mistake

The goal was a method that returns 0 on an error, so return was written right in finally, since it always runs:

C#
Console.WriteLine(Read("5"));

int Read(string text)
{
    try
    {
        return int.Parse(text);
    }
    finally
    {
        return 0; // ✗
    }
}
TEXT
error CS0157: Control cannot leave the body of a finally clause

The program does not compile: you cannot leave the body of finally through return. A finally block only tidies up, and a default value can be returned from catch: catch (FormatException) { return 0; }.

Key points

  • finally runs on every way out of try: after the normal end, after catch, after return and after an exception that goes on.
  • With return, the value is computed before finally, and the method returns it after.
  • finally holds what must be done in any case: turn off the stove, close a file.
  • A return in finally itself is forbidden: error CS0157.