Where is finally needed?

I know how to use try-catch-finally. However, I am not getting the promotion of using finally , since I can always put code after the try-catch block. Is there a clear example?

+8
c # exception finally
source share
11 answers

Refresh . This is actually a great answer. On the other hand, maybe this is a good answer, because it illustrates a great finally example, succeeding where the developer (i.e. I) may not provide the proper cleanup. In the code below, consider a scenario in which an exception other than a SpecificException thrown. Then the first example will still perform the cleanup, while the second will not, although the developer might think: "I caught the exception and handled it, so of course the subsequent code will work."


Anyone who gives reason to use try / finally without catch . This might make sense with catch , even if you throw an exception. Consider case * where you want to return a value.

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

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

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

* I believe that the best example of try / catch / finally is when an exception is re-thrown (using throw , not throw ex , but this is a different topic) into the catch , and therefore finally needed as without it after try / catch will not work. This is usually done using the using statement on the IDisposable resource, but this is not always the case. Sometimes cleaning is not a Dispose call (or it is more than just a Dispose call).

+1
source share

You need to finally, because you do not always have to catch:

 void M() { var fs = new FileStream(...); try { fs.Write(...); } finally { fs.Close(); } } 

The above method does not catch errors when using fs , leaving them to the caller. But he must always close the stream.

Note that this type of code usually uses the using() {} block, but this is just a shorthand for try / finally. To be complete:

  using(var fs = new FileStream(...)) { fs.Write(...); } // invisible finally here 
+4
source share

It is almost always used for cleaning, usually implicitly using the using statement:

 FileStream stream = new FileStream(...); try { // Read some stuff } finally { stream.Dispose(); } 

Now this is not equivalent

 FileStream stream = new FileStream(...); // Read some stuff stream.Dispose(); 

because the code "read some material" may cause an exception or possibly return - and, nevertheless, it ends, we want to get rid of the stream.

So finally blocks are usually used to clear resources. However, in C # they are usually implicit using the using statement:

 using (FileStream stream = new FileStream(...)) { // Read some stuff } // Dispose called automatically 

finally blocks are much more common in Java than in C #, precisely because of the using statement. I very rarely write my own finally blocks in C #.

+4
source share
 try { DoSomethingImportant(); } finally { ItIsRidiculouslyImportantThatThisRuns(); } 

When you have a finally block, the code in it will be guaranteed to work after exiting the attempt. If you put the code outside of try / catch, it is not. A more common example is one that is used 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 are deleted and released even if an exception occurs during try .

* Please note that there are situations when management does not exit the attempt, and finally, it does not actually start. As a simple example, a PowerFailureException .

+3
source share

The code placed in the finally block is executed even if:

  • there are return in a try or catch
    OR
  • catch repeats exception

Example:

 public int Foo() { try { MethodThatCausesException(); } catch { return 0; } // this will NOT be executed ReleaseResources(); } public int Bar() { try { MethodThatCausesException(); } catch { return 0; } finally { // this will be executed ReleaseResources(); } } 
+2
source share

you do not necessarily use it with exceptions. You may have try/finally do some cleanup before each return in a block.

+1
source share

The finally block is always executed regardless of the error received or not. It is commonly used for cleaning purposes.

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

+1
source share

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

0
source share

I'm not sure how this is done in C #, but in Delphi you will find the β€œlast” very often. The key word is manual memory management.

 MyObject := TMyObject.Create(); //Constructor try //do something finally MyObject.Free(); end; 
0
source share

If an exception occurs (or rises) in the catch block, the code will not be executed after the catch - on the contrary, the code inside finally will still be executed.

In addition, the code inside finally finally executes even when exiting the return method.

Finally, it is especially convenient to deal with external resources, such as files that need to be closed:

 Stream file; try { file = File.Open(/**/); //... if (someCondition) return; //... } catch (Exception ex) { //Notify the user } finally { if (file != null) file.Close(); } 

Note that in this example, you can also use:

 using (Stream file = File.Open(/**/)) { //Code } 
0
source share

For example, during the process you can disable WinForm ...

 try { this.Enabled = false; // some process } catch(Exception ex) { MessageBox.Show(ex.Message); } finally { this.Enabled = true; } 
0
source share

All Articles