views:

152

answers:

4

Can exceptions be caught inside a using block, and if so what is the syntax?

So, something like the following:

using (var creatingThing = new MyCreatingThing())
{
    creatingThing.CreateSomething();

    catch()
    {
        creatingThing.Rollback();
    }
}

Can this be done? Or do I need to write this code manually (ie without a using)?

+6  A: 

You cannot implicitly enlist in the try...finally block that the compiler generates (for the using statement). You have to add another try statement, which will be nested within the generated block:

using (var creatingThing = new MyCreatingThing())
{
    try
    {
        creatingThing.CreateSomething();
    }   
    catch
    {
        creatingThing.Rollback();
    }
}
Jeff Sternal
But that won't catch a exception thrown by the constructor (although the action he has in the catch would be a problem if the ctor threw the exception)
James Curran
ok, so there's no way to hook into the implicit `try... finally` created by the using?
fearofawhackplanet
@fear: Correct.
Steven Sudit
+3  A: 

Sure, just add the try inside the using:

using (var creatingThing = new MyCreatingThing())
{
    try
    {
    creatingThing.CreateSomething();
    }
    catch(Exception ex)
    {
        creatingThing.Rollback();
    }
}
ho1
This syntax is incorrect.
Steven Sudit
@steven: Yes, just wanted to show how to add the `try` bit so didn't worry about the rest, but it's probably best for all of it to be correct.
ho1
No harm done. This is why I prefer to comment instead of blindly downvote. :-)
Steven Sudit
+15  A: 

You can put a try/catch inside the using statement, or outside:

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

Or...

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

However, you can't just put a catch block without a try block.

Choose the right one based on what whether you need to catch exceptions which are thrown by the resource acquisition expression, whether you want the resource to be disposed before your catch block is executed, and whether you need access to the resource variable within the catch block.

Jon Skeet
Jon, in your second code example, if an exception is thrown inside the using part of the try block, will the resource still be disposed?
Maxim Zaslavsky
@Maxim: Yes, absolutely.
Jon Skeet
+6  A: 

Note, the a using is really a try/finally under the covers, so it may be easier the code it that way:

MyCreatingThing creatingThing = null;
try
{
    creatingThing = new MyNCreatingThing())
    creatingThing.CreateSomething(); 
}    
catch() 
{ 
      Console.WriteLine("An Exception happened");
      if (creatingThing !=null)
          creatingThing.Rollback(); 
}
finally
{
      if (creatingThing !=null)
           creatingThing.Dispose(); 
}
James Curran
You might want to cast `creatingThing` to `IDisposable`, in case it's implemented explicitly.
Steven Sudit