2

Possible Duplicate:
If I return a value inside a using block in a method, does the using dispose of the object before the return?

I have this code (simplyfied):

bool method1()
{
      using (OleDbConnection con = new OleDbConnection(connString))
            {
                bool b = false;

                try
                {
                    con.Open();
                    b = true;

                }
                catch (Exception)
                {
                    b = false;
                }
                finally
                {
                    con.Close();
                    return b;
                }                
            }
}

I return before the closing curly bracket of the "using" statment. Does my object "con" gets Disposed anyway? Is is better to use the following code?:

bool method1()
{
      bool b = false;
      using (OleDbConnection con = new OleDbConnection(connString))
            {
                try
                {
                    con.Open();
                    b = true;

                }
                catch (Exception)
                {
                    b = false;
                }
                finally
                {
                    con.Close();                    
                }                
            }

        return b;
}
Community
  • 1
  • 1
Broken_Window
  • 2,037
  • 3
  • 21
  • 47

5 Answers5

4

The whole point of the using statement is that it automates the disposal of an object, even if an unhandled exception is thrown from within the using block.

Therefore, once your code exits the using block, whether it's returning or otherwise, then the object being 'used' us disposed.

Rich Turner
  • 10,800
  • 1
  • 51
  • 68
  • Note also that because of this, you don't need to call `Close()` explicitly as you have done. If you decompile `OleDbConnection` you will see that Dispose calls Close – Rhumborl Jan 12 '13 at 14:39
  • @Rhumborl: thanks for the tip. I came from an unmanaged world (VB6 C++), so I easily get confused with the Garbage Collector stuff. – Broken_Window Jan 12 '13 at 14:42
  • Y3L1NNa - You get +1 for atleast using using. Forget most of all you knew about VB and C++ and let C#/NET stand omn its own accord. Later, you can compare and appreciate both VB and C++, once you get used to the 'managed code, managed data' paradigm. Happy Coding – Michael Viktor Starberg Jan 12 '13 at 15:05
2

It is completely safe to return during a using statement due to the .NET magic of automatically handling disposal of objects. The whole idea is that you don't have to think about how you exit out of the using block, you just know that when you leave it the object will be disposed correctly. Because of such, your example could be simplified to this:

bool method1()
{
    using (OleDbConnection con = new OleDbConnection(connString))
        {
            try
            {
                con.Open();
                return true;
            }
            catch (Exception)
            {
                return false;
            }          
    }
}

con.Close() can be removed as well as it is automatically called by the disposal.

Look at this if you want to see what happens under the hood.

Community
  • 1
  • 1
Phil
  • 351
  • 3
  • 7
1

there is no difference between two code sections; con object will be disposed in both examples.

daryal
  • 14,643
  • 4
  • 38
  • 54
1

In the first example you set a temporary variable and return that.

About the return in the finally: What happens after compilation is that you branch to the end of the method and then return a temporary variable.

E.g. the results is exactly the same. Just for clarity I would personally prefer the first one, because it resembles what happens more exactly.

atlaste
  • 30,418
  • 3
  • 57
  • 87
0

using expands into somewhat more complex with additional if statement like

OleDbConnection con = new OleDbConnection(connString)
try
{
    con.Open();
}
finally
{
    // Check for a null resource.
    if (con != null)
        // Call the object's Dispose method.
        ((IDisposable)con).Dispose();
}  

So in your example you might get NullReferenceException in finally block.

So if you want to return the status of operation and Dispose and object, I suggest to use this code snippet

using(OleDbConnection con = new OleDbConnection(connString))
{
    try
    {
        con.Open();
        return true;
    }catch(OleDbException ex)
    {
        //log error
        return false;
    }
}
Peter O.
  • 32,158
  • 14
  • 82
  • 96
Ilya Ivanov
  • 23,148
  • 4
  • 64
  • 90
  • I chose this one as the answer because it is the most accurate to my specific case AND I didn't notice I could get a NullReferenceException in some scenarios. Thanks! – Broken_Window Jan 12 '13 at 14:55
  • please note not to catch `Exception` in catch block. Just catch specific `OleDbException` exceptions. But event in this case, I would consider making method `void` and not to return some flag. It makes exception for exceptional cases, not for normal flow of logic. – Ilya Ivanov Jan 12 '13 at 15:01