Search code examples
c#finally

Is finally block in C# a must?


What is the difference between 2 conditions? Every time when method1 or method2 runs, there should be a code block that is required to run. It seems to me that 2 method are the same.

// example method1
void Method1(void)
{
    try
    {
        // do something
    }
    catch (Exception ex)
    {
        // do something
    }
    finally
    {
        // do something whenever method1 runs
    }
}

// example method2
void Method2(void)
{
    try
    {
        // do something
    }
    catch (Exception ex)
    {
        // do something
    }

    // do something whenever method2 runs
}

Finally block seems to be unnecessary for me.


Solution

  • In your first example, you could re-throw the exception and the code inside the finally would still run. This would not be possible in the second example.

    If you choose not to re-throw the exception, then yes there is little difference. However, this is considered bad form - very rarely should you need to consume an exception that you cannot explicitly handle.

    It is a keyword to help you with code execution flow. When you throw an exception the execution flow of the code is affected (like using return), the finally keyword allows you to express that when an exception occurs (or you return from a try) you still want execution to do something as it's leaving.

    To answer the question facetiously, it is a must when you need it and not when you don't.


    Further Reading

    To be on the safe side, before you attempt to start making use of this keyword, please read the documentation for it:

    http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx

    And the exception handling keywords in general:

    http://msdn.microsoft.com/en-us/library/s7fekhdy.aspx


    Examples

    Catch an exception to do something with it, then re-throw it. Use finally to call any tidy-up code:

    try
    {
        OpenConnectionToDatabase();
        // something likely to fail
    }
    catch (Exception ex)
    {
        Log(ex);
        throw;  
        // throw ex; // also works but behaves differently
    }
    // Not specifying an exception parameter also works, but you don't get exception details.
    //catch (Exception)
    //{
    //    Log("Something went wrong);
    //    throw;
    //}
    finally
    {
        CloseConnectionToDatabase();
    }
    

    Don't register any interest in catching exceptions, but use finally to tidy-up code:

    try
    {
        OpenConnectionToDatabase();
        // something likely to fail
    }
    finally
    {
        CloseConnectionToDatabase();
    }
    

    Return from your try because it looks nicely formatted, but still use finally to tidy-up code:

    try
    {
        OpenConnectionToDatabase();
        return 42;
    }
    finally
    {
        CloseConnectionToDatabase();
    }