The difference between try {..} catch {...} with and without ending

What is the difference between the following code:

string path = @"c:\users\public\test.txt"; System.IO.StreamReader file = new System.IO.StreamReader(path); char[] buffer = new char[10]; try { file.ReadBlock(buffer, index, buffer.Length); } catch (System.IO.IOException e) { Console.WriteLine("Error reading from {0}. Message = {1}", path, e.Message); } finally { if (file != null) { file.Close(); } } 

and this:

 string path = @"c:\users\public\test.txt"; System.IO.StreamReader file = new System.IO.StreamReader(path); char[] buffer = new char[10]; try { file.ReadBlock(buffer, index, buffer.Length); } catch (System.IO.IOException e) { Console.WriteLine("Error reading from {0}. Message = {1}", path, e.Message); } if (file != null) { file.Close(); } 

In fact, in this design it is really necessary to block. Why did Microsoft provide such a design? He seems to be superfluous. Is not it?

+6
source share
5 answers

Imagine if any other exception occurred that you did not handle, for example. a ArgumentOutOfRangeException , or if you want to throw an exception or throw a wrapped exception from a catch block:

  • The first block ensures that the file is closed regardless of whether an exception has occurred.

  • The second block will only close the file if no exception has occurred or an IOException occurred. It does not handle other cases.

+9
source

The first block will close the file, even if there is an uncaught exception.

The second block will close the file only if there are no exceptions or any abandoned exceptions are caught.

The first also ensures that the file will be closed if try has a break , goto , return , continue or any other transition construct that causes execution to move outside of the try block. The second does not, and as such can lead to the fact that the resource will not be closed.

+6
source

In your example, if your code throws an exception other than System.IO.IOException , your cleanup code will not work. With a finally block, the code inside it will work no matter what type of exception is thrown.

+2
source

Suppose there was an exception inside catch{} , the code will still execute inside the code, but there will be no if (file != null){} block.

0
source

In this case, he is superfluous.

This is useful if, for example, you throw an exception and still want some code to run after the block:

 try { // do something dangerous } catch(...) { // log the error or something throw; // let the exception bubble up to the caller } finally { // this always runs } // this only runs if there was no exception 

Another example: if catch can throw an exception for another reason:

 try { // do something dangerous } catch(...) { // handle the error // log the error, which may cause a different exception } finally { // this runs even if the catch crashed } // this only runs if there was no exception, or the code in the catch worked 

Simple, since code can crash for many reasons that you don’t even know about, it is useful to put a cleanup in the finally block to make sure that it works no matter what happens.

0
source

Source: https://habr.com/ru/post/957457/


All Articles