Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

What's the point in a try without a catch?


It's unlikely you always want to handle an exception where you happen to be doing file I/O. You still want to close the file and dispose of the handle but you might want to handle any exceptions higher up in client code. Or you might want a file I/O exception to fly high and cause your program to exit.


the finally block is always executed, then the exception is thrown. So

    try { dobadthing(); }
    finally { cleanup(); }
calls dobadthing(), which throws an exception; then cleanup() is called in case some recovery can be done, then the exception is thrown as if there were no try block.


Yes, I understand how finallys work. I was questioning why you wouldn't want to catch dobadthing().


Something higher up can catch, if need be. this way you can write a function which is supposed to throw exceptions in cases of failure, but not leave resources hanging about. An example would be executing arbitrary SQL; you might want to do;

  01 void ExecuteSql(string sql)
  02 {
  03   connection.Open();
  04   try
  05   {
  06     // execute SQL
  07   }
  08   finally
  09   {
  10     connection.Close();
  11   }
  12 }
And the effect here is that you have a function which still throws if your SQL is bad, but doesn't have the side-effect of leaving you with an open connection dangling about. That feels like a safer function to call.

try/finally isn't something I find myself using very often at all, I think because the IDisposable pattern is actually translated into it - the code above is (nearly?) equivalent to;

  connection.Open();
  using(connection)
  {
    // execute SQL
  }
so I guess IDisposable is the preferred way in MS' codebase.

(All code is typed late at night into a textbox and totally untested. ;) )

PS: @politician confirms that `using` is translated to try/finally (http://news.ycombinator.com/item?id=3440969) so that's why you don't see it much -- `using` is syntactic sugar for it.


IMO the big benefit of 'using' statements is that they have the ability to incorporate RAII-type semantics (the idea of scoped resource lifetimes) into C#, which normally doesn't have them, via objects that implement the IDisposable interface. It can make it cleaner and less error-prone to have the language perform cleanup for you automatically than relying on the user to do so himself.


AS I argued elsewhere[1], exploiting the way C# handles `foreach` is a better way of achieving RAII IMHO; it forces the client code to do the right thing rather than hoping it will remember to use the `using` statement (or manually call Dispose()).

[1]http://news.ycombinator.com/item?id=3423426


Cost of not disposing isn't really high enough to be worth such code-obfuscating contortions.

The garbage collector makes sure objects are properly disposed of. The only real cost to letting the collector handle it is that the object ends up surviving for an extra GC cycle. It's sloppy practice, and it means memory consumption will be higher if your program rapidly generates a lot of short-lived IDisposables, but otherwise the difference will probably be trivial.


I'm not saying to avoid IDisposable (just the opposite in fact).

The `foreach` statement and the `using` statement just so happen to desugar to similar code when it comes to handling IDisposable. The C# compiler will guarantee that Dispose() is called on the iterator and that code in the `finally` block will execute... even if you exit the loop early due to an `exception` or a break/goto. Just like the `using` statement.

The benefit is that it's even more of a pit-of-success feature than the `using` statement because you can't possibly forget to call Dispose().

It's also only slightly more work for the library author and slightly less work for the client but the client is going to use the code many more times than the author will write it.


Another strong use-case involves database transactions (TransactionScope).


In this case, the handle gets closed even if an exception is thrown.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: