Try / Finally a block against calling dispose?

Is there a difference between the two code samples, and if not, why does using exist?

 StreamWriter writer; try { writer = new StreamWriter(...) writer.blahblah(); } finally { writer.Dispose(); } 

vs

 using (Streamwriter writer = new Streamwriter(...)) { writer.blahblah } 

I mean, in the second example, you really have to put it in a try block anyway, so adding a finally block really doesnโ€™t take much effort. I understand that all of this can be included in a larger try block, but yes, it just seems to me superfluous.

+6
source share
6 answers

There are some problems in the code. They never write like this ( use instead), and therefore:

 StreamWriter writer; try { // What if you failed here to create StreamWriter? // Eg you haven't got permissions, the path is wrong etc. // In this case "writer" will point to trash and // The "finally" section will be executed writer = new StreamWriter(...) writer.blahblah(); } finally { // If you failed to execute the StreamWriter constructor // "writer" points to trash and you'll probably crash with Access Violation // Moreover, this Access Violation will be an unstable error! writer.Dispose(); } 

When you put "use" this way

  using (StreamWriter writer = new StreamWriter(...)) { writer.blahblah(); } 

It is equal to the code

 StreamWriter writer = null; // <- pay attention to the assignment try { writer = new StreamWriter(...) writer.blahblah(); } finally { if (!Object.ReferenceEquals(null, writer)) // <- ... And to the check writer.Dispose(); } 
+6
source

Is there a difference between these two code examples

Yes, using checks for null before calling Dispose (i.e., the actual code that it extends introduces a null check).

Why does use exist?

Because the code is shorter. Just syntactic sugar.

+7
source

What you wrote is pretty much a template that using completes. And so this is the using point to keep the need to write the same try....finally block every time you use the Disposable object.

Regarding your edited question

[...] in the second example you really have to put it in a try block anyway, so adding a finally block really doesnโ€™t take much effort

Most likely, you cannot (or do not want to) handle this error from blahblah explicitly, and you just want it to run before the calling code ... but still cleared your StreamWriter resources along the way!

So you are done with this:

 StreamWriter writer; try{ writer = new StreamWriter(...) writer.blahblah(); }catch{ throw; // pointless! } finally [ writer.Dispose(); } 
+6
source

First of all, using using is safer than your code , it handles errors in the construction of the Disposable object correctly and will not call dispose on the null object.

The second difference in code readability is to look at your example. The first version takes 7 lines. The second is only 3.

+1
source

The latter is simply syntactic sugar for the former. They should do the same, but the latter requires less template code.

I would recommend using using one, as the probability of an error may be less likely.

+1
source

They are not exactly the same. The try / finally block does not protect against stupid errors.

 StreamWriter writer = new StreamWriter(...); try { ... writer = new StreamWriter(...); ... } finally { writer.Dispose(); } 

Please note that only the second is recorded. On the contrary

 using (StreamWriter writer = new StreamWriter(...)) { ... writer = new StreamWriter(...); ... } 

will give a compile time error.

+1
source

All Articles