9

If I have a using block surrounding a try catch statement what will happen to the object inside that using statement should the catch fire an exception? Consider the following code:

using (IDatabaseConnectivityObject databaseConnectivityObject = new DbProviderFactoryConnectionBasicResponse())
{
    try
    {
        Foo();
    }
    catch (ArgumentNullException e)
    {
        throw;
    }
}

If we assume Foo() fails and the exception is fired and effectively breaks the program will databaseConnectivityObject be disposed? The reason this is important is that the object has a database connection associated with it.

abatishchev
  • 98,240
  • 88
  • 296
  • 433
CSharpened
  • 11,674
  • 14
  • 52
  • 86

5 Answers5

12

You can think of using as a short-hand for try-finally. Hence your code is equivalent to:

IDatabaseConnectivityObject databaseConnectivityObject = new DbProviderFactoryConnectionBasicResponse();
try
{
    try
    {
        Foo();
    }
    catch(ArgumentNullException e)
    {
        throw;
    }
}
finally
{
  if(databaseConnectivityObject != null)//this test is often optimised away
    databaseConnectivityObject.Dispose()
}

Looked at this way, you can see that the Dispose() will indeed be called if the exception throws, because the try-finally is outside of the try-catch.

This is precisely why we use using.

Jon Hanna
  • 110,372
  • 10
  • 146
  • 251
7

we assume Foo() fails and the exception is fired and effectively breaks the program will databaseConnectivityObject be disposed?

Yes it will be. using internally uses try-finally, (using only works for those which implements IDisposable)

From MSDN- using statement

The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object. You can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block; in fact, this is how the using statement is translated by the compiler.

Habib
  • 219,104
  • 29
  • 407
  • 436
  • So in effect the using is saying try all the code within the using block and finally call MyObject.Dispose() in the finally block that we do not see? – CSharpened Sep 03 '12 at 10:24
  • 1
    @CSharpened, absolutely right, that is the case. you can see more detailed example on the link in the answer – Habib Sep 03 '12 at 10:25
3

Yes your using block will dispose of the databaseConnectivityObject, irrespective of whether you have a try - catch block.

You rightly say that the using block is important and you should use it for all classes that implement IDisposable to ensure that they get disposed of properly even in the event of an exception.

From MSDN- using statement

The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object. You can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block; in fact, this is how the using statement is translated by the compiler.

cspolton
  • 4,495
  • 4
  • 26
  • 34
3

When implementing the using block the object in the parentheses will be disposed if it implements the IDisposable interface.

It would still be disposed even if foo() failed.

The object inside the using statement must implement the IDisposable interface.

Also, these questions "Uses of using in c sharp" and "using statement vs try finally" speak further on the uses and practicalities of the using statement.

Section 8.13 of the C# Language Specification details the using statement clearly.

Community
  • 1
  • 1
Mr. Mr.
  • 4,257
  • 3
  • 27
  • 42
2

Your using code is equivalent to

IDatabaseConnectivityObject databaseConnectivityObject = new IDatabaseConnectivityObject ();
try
{
//To do code here
}
finally
{
    if(databaseConnectivityObject!=null)
    {
       databaseConnectivityObject.Dispose();
    }
}

A using statement mainly categorized into three part i.e.

  1. Acquisition
  2. Usage
  3. Disposal

Firstly, the resources is acquired and the usage is made on the try block with finally statement.At last, the object is disposed in finally block as given in above equivalent code....

Akash KC
  • 16,057
  • 6
  • 39
  • 59
  • 1
    I think it's worth pointing out that the null-test is typically optimised away when it can be, when explaining it. Someone might be tempted to do their own try-finally as a micro-optimisation. That'd be a bad idea anyway (the reduction in legibility wouldn't be worth it), but the fact that it won't even offer the tiny benefit they think it might, will discourage it further. – Jon Hanna Sep 03 '12 at 10:28