Where the finally is necessary?

2019-04-22 19:31发布

I know how to use try-catch-finally. However I do not get the advance of using finally as I always can place the code after the try-catch block. Is there any clear example?

11条回答
家丑人穷心不美
2楼-- · 2019-04-22 20:00
try 
{
    DoSomethingImportant();
}
finally
{
    ItIsRidiculouslyImportantThatThisRuns();
}

When you have a finally block, the code therein is guaranteed to run upon exit of the try. If you place code outside of the try/catch, that is not the case. A more common example is the one utilized with disposable resources when you use the using statement.

using (StreamReader reader = new StreamReader(filename))
{
}

expands to

StreamReader reader = null;
try
{
    reader = new StreamReader(filename);
    // do work
}
finally 
{
    if (reader != null)
       ((IDisposable)reader).Dispose();
}

This ensures that all unmanaged resources get disposed and released, even in the case of an exception during the try.

*Note that there are situations when control does not exit the try, and the finally would not actually run. As an easy example, PowerFailureException.

查看更多
forever°为你锁心
3楼-- · 2019-04-22 20:00

I am not sure how it is done in c#, but in Delphi, you will find "finally" very often. The keyword is manual memory management.

MyObject := TMyObject.Create(); //Constructor
try 
     //do something
finally
    MyObject.Free(); 
end;
查看更多
神经病院院长
4楼-- · 2019-04-22 20:03

Update: This is actually not a great answer. On the other hand, maybe it is a good answer because it illustrates a perfect example of finally succeeding where a developer (i.e., me) might fail to ensure cleanup properly. In the below code, consider the scenario where an exception other than SpecificException is thrown. Then the first example will still perform cleanup, while the second will not, even though the developer may think "I caught the exception and handled it, so surely the subsequent code will run."


Everybody's giving reasons to use try/finally without a catch. It can still make sense to do so with a catch, even if you're throwing an exception. Consider the case* where you want to return a value.

try
{
    DoSomethingTricky();
    return true;
}
catch (SpecificException ex)
{
    LogException(ex);
    return false;
}
finally
{
    DoImportantCleanup();
}

The alternative to the above without a finally is (in my opinion) somewhat less readable:

bool success;

try
{
    DoSomethingTricky();
    success = true;
}
catch (SpecificException ex)
{
    LogException(ex);
    success = false;
}

DoImportantCleanup();
return success;

*I do think a better example of try/catch/finally is when the exception is re-thrown (using throw, not throw ex—but that's another topic) in the catch block, and so the finally is necessary as without it code after the try/catch would not run. This is typically accomplished with a using statement on an IDisposable resource, but that's not always the case. Sometimes the cleanup is not specifically a Dispose call (or is more than just a Dispose call).

查看更多
做个烂人
5楼-- · 2019-04-22 20:03

you don't necessarily use it with exceptions. You may have try/finally to execute some clean up before every return in the block.

查看更多
看我几分像从前
6楼-- · 2019-04-22 20:11

The finally block always is executed irrespective of error obtained or not. It is generally used for cleaning up purposes.

For your question, the general use of Catch is to throw the error back to caller, in such cases the code is finally still executes.

查看更多
一纸荒年 Trace。
7楼-- · 2019-04-22 20:12

The finally block will always be executed even if the exception is re-thrown in the catch block.

查看更多
登录 后发表回答