views:

400

answers:

7

I understand the point of "using" is to guarantee that the Dispose method of the object will be called. But how should an exception within a "using" statement be handled? If there is an exception, I need to wrap my "using" statement in a try catch. For example:


Lets say there is an exception created in the creation of the object inside the using parameter

 try
 {
    // Exception in using parameter
    using (SqlConnection connection = new SqlConnection("LippertTheLeopard"))
    {
       connection.Open();
    }
 }
 catch (Exception ex)
 {

 }

Or an Exception within the using scope

 using (SqlConnection connection = new SqlConnection())
 {
    try
    {
       connection.Open();
    }
    catch (Exception ex)
    {

    }
 }

It seems like if I already need to handle an exception with a try catch, that maybe I should just handle the disposing of the object as well. In this case the "using" statement doesn't seem to help me out at all. How do I properly handle an exception with "using" statement? Is there a better approach to this that I'm missing?

 SqlConnection connection2 = null;
 try
 {
    connection2 = new SqlConnection("z");
    connection2.Open();
 }
 catch (Exception ex)
 {

 }
 finally
 {
    IDisposable disp = connection2 as IDisposable;
    if (disp != null)
    {
       disp.Dispose();
    }
 }

Could the "using" keyword syntax be a little more sugary...
It sure would be nice to have this:

 using (SqlConnection connection = new SqlConnection())
 {
    connection.Open();
 }
 catch(Exception ex)
 {
   // What went wrong? Well at least connection is Disposed
 }
+12  A: 

using Has nothing to do with error handling. It's shorthand for "call Dispose when you leave this block." Your second code example is perfectly acceptable... why mess with what works?

Dave Swersky
The point of the question is, why does using not have an optional catch block. It's more rhetorical unless you work at Microsoft.
Chap
I wouldn't do the 2nd example. imo it's an example of handling an error at the wrong level. Let it 'bubble up' to the calling function.
Joel Coehoorn
@Joel agreed in the larger scope of things, that's the way I'd do it if you had a reason to do any error handling at that level.
Dave Swersky
Well, why doesn't `if` or `while` has an optional `catch` block? A better question is, why should it? `catch` goes together with `try`, like `else` goes together with `if`.
Pavel Minaev
It's more rhetorical EVEN if you work at Microsoft :)
Kirill Osenkov
+2  A: 

An interesting idea, but it would make the following kinda confusing:

 using (SqlConnection connection = new SqlConnection())
 using (SqlCommand cmd = new SqlCommand())
 {
     connection.Open();
 }
 catch(Exception ex)
 {
     // Is connection valid? Is cmd valid?  how would you tell?
     // if the ctor of either throw do I get here?
 }
csharptest.net
Your example isn't valid. "Stacked" using statements aren't a language feature. Your code is equivalent to nesting the second using inside of the block of the first using. This is no different than writing two if-statements back to back without curly braces.
David Pfeffer
If you'd want to catch each exception individually you could nest the using blocks. I actually like the OP's idea even though I'm sure they'll never implement it in the language. Not useful enough, and potentially confusing.
Meta-Knight
@bytenik: that's irrelevant. This code could still confuse people. It doesn't matter that it's not a special feature.
Joel Coehoorn
+6  A: 

The using block is just syntactic sugar for a try-finally block. If you need a catch clause, just use a try-catch-finally:

SqlConnection connection;
try 
{
    connection = new SqlConnection();
    connection.Open();
}
catch(Exception ex)
{
    // handle
}
finally 
{
    if (connection != null)
    {
        connection.Dispose();
    }
}

Yes, this is more code than your theoretical "using-catch"; I judge the language developers didn't consider this a very high priority, and I can't say I've ever felt its loss.

Michael Petrotta
You will exit the using statement block when an exception is thrown so a try/catch is better imo.
ChadNC
@ChadNC: apparently you don't understand `using` - it protects you from exceptions and will dispose the object anyway.
Joel Coehoorn
+4  A: 
Joel Coehoorn
+1 This is a great point. The exception probably should be handled up at the next level.
SwDevMan81
+24  A: 

Because you would be 'hiding' extra functionality inside an unrelated keyword.

However you could always write it this way

using (...) try
{
}
catch (...)
{
}

And this way the line represents your intentions -- a using statement that is also a try

Kevin Laity
That's a short and clean way to do it.
Meta-Knight
Nice, that does seem to handle any errors inside the using, although it doesnt cover the exception in the using parameter. Good to know though
SwDevMan81
Ooh, I like this. Wish I could upvote it twice.
Joel Coehoorn
Gave you your 10th vote for a badge here instead: http://stackoverflow.com/questions/636384/is-it-more-important-to-get-the-problem-done-or-to-write-programs-that-are-easy-t/636448#636448
Joel Coehoorn
Ok, after thinking about this, this is the same as my second example.
SwDevMan81
Indeed, but much less verbose. It looks like it actually fits rather than something that was hacked together.
Joel Coehoorn
Very pretty. +1.
Dave Swersky
@Joel Coehoorn: Thank you very much, it's always great to hear positive feedback from a higher ranking member like yourself :)
Kevin Laity
Rep hardly == skill or expertise, but I appreciate the sentiment. ;)
Joel Coehoorn
Wow, this is cool.
Kirill Osenkov
+1  A: 

You are mixing concerns in my opinion. Resource management (i.e. disposale of objects) is completely separated from exception handling. The one-to-one mapping that you describe in your question is just a very special case. Usually exception handling will not happen in the same place as the using scope ends. Or you might have multiple try-catch regions inside a using block. Or ...

Achim
the purpose of a finally block is to make sure resources are cleaned up. in a case of using { try {} catch {} finally {} } the using becomes redundant
Matt Briggs
Yes, but why use `finally`? In most cases, wrapping `try/catch` inside `using` is clearer _and_ shorter still.
Pavel Minaev
A: 

I recommend you use example #1 and #2 combined. The reason is your using statement could read a file, for instance, and throw an exception (i.e File Not Found). If you don't catch it, then you have an unhandled exception. Putting the try catch block inside the using block will only catch exceptions that occur after the using statement has executed. A combination of your example one and two is best IMHO.

0A0D