0

In some code I routinely work with (and have written a few times), code like the following has been used:

using (StreamWriter sw = new FileWriter(".\SomeFile.txt"))
{
    // Perform file IO here...
}
finally
{
    sw.Close();
}

I'm familiar with try/catch/finally in C#...I know that context of finally works. When I performed a google search on the terms "Finally Using", I could find no relevant matches.

Does this context of Finally work as I'm thinking, where upon the final command of the Using statement, the contents of the Finally block get executed? Or do I (and the code base I'm working with) have this all wrong; is Finally restricted to Try/Catch?

Andrew Gray
  • 3,756
  • 3
  • 39
  • 75
  • I have never seen such a `using`/`finally` combination before. BTW, why calling `Close()` explicitly? – sloth Jul 18 '12 at 14:03
  • I'm not sure, to be honest, this is code I had seen from others originally. I think the intent was that, for certain unmanaged resources (File IO, DB Connections) a cleanup needs to manually occur, because either A) a Dispose may not be defined, or B) a Dispose may not clean up everything, depending on how the author of that 'resource' chose to implement it. – Andrew Gray Jul 18 '12 at 14:27

4 Answers4

1

Finally always runs, but your code as it stands is mostly redundant. The code:

 using (StreamWriter sw = new FileWriter(".\SomeFile.txt"))
 {
     // Perform file IO here...
 }

Is functionally equivalent to

 {
   StreamWriter sw = new FileWriter(".\SomeFile.txt");
    try {
       // Perform file IO here...
    }
    finally {
       ((IDisposable)sw).Dispose();
    }
 }

StreamWriter's Dispose() method implicitly calls Close(). However this should not be an error because user-defined Finallys run before system-implicit Finallys.

tmesser
  • 7,558
  • 2
  • 26
  • 38
  • 1
    It's vice versa: `StreamWriter.Close()` calls its `Dispose` method. – sloth Jul 18 '12 at 14:05
  • Haha, you got me curious so I double checked in reflector. Amusingly enough, we're both right. `Dispose()` will call `this.stream.Close()` if it's required, while `Close()` will immediately call the `Dispose()`. Pastebin here: http://pastebin.com/BbcEqVwg – tmesser Jul 18 '12 at 14:45
1

is Finally restricted to Try/Catch?

Yes. A finally block must be preceded by a try block. Only catch is optional. Besides that you should read a bit about scope. The sw variable you declare in the using block is not accessible outside that block.

Furthermore the using will dispose the StreamWriter (FileWriter is from Java ;-) as soon as the block goes out of scope (i.e. when the last instruction in that block is executed) so you don't have to discard or Close it manually.

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
0

Finally always works, whether or not there is an (uncaught) exception doesn't matter

Gerald Versluis
  • 30,492
  • 6
  • 73
  • 100
0

I believe that when a using is converted to IL - .Net converts a using to a try (of sorts) anyway - And so it will still make sense in this context.

See this article.

El Ronnoco
  • 11,753
  • 5
  • 38
  • 65