-3

Consider this class:

class Person : IDisposable
{
    public Person(int age)
    {

    }
    public void Dispose()
    {
        Console.WriteLine("Dispose");
    }
}

and this code:

using (Person perosn = new Person(0))
{
   using (Person child = new Person(1))
   {
   }
}

When run this code output is two Dispose in console.

I change the class:

class Person : IDisposable
{
    public Person(int age)
    {
        if (age == 1)
        {
            throw new Exception("Person");
        }
    }
    public void Dispose()
    {
        Console.WriteLine("Dispose");
    }
}

I get exception and both class does not dispose.

So why when I throw new exception in child's constructor, both classes are not disposed?

Suhaib Janjua
  • 3,538
  • 16
  • 59
  • 73
  • 1
    This doesn't worth much upvotes as question is providing wrong information. – Sriram Sakthivel Mar 03 '14 at 05:57
  • Cannot reproduce. When constructor in inner using throws an exception I still see outer using disposing of class correctly. – LeffeBrune Mar 03 '14 at 06:01
  • Some useful reading is Eric Lippert's post about the interactions of exceptions and `using` statements [here](http://blog.coverity.com/2014/02/26/resources-vs-exceptions/#.UxQ2bnVdWlg). – Mike Zboray Mar 03 '14 at 08:02

3 Answers3

3

I'm not seeing the same results:

try {
    using (Person perosn = new Person(0))
    {
        using (Person child = new Person(1))
        {
        }
    }
} catch {
    Console.WriteLine("Caught exception");
}

Output:

Dispose
Caught exception
Blorgbeard
  • 101,031
  • 48
  • 228
  • 272
  • I think the asker wanted two know why the output `Disposed` is written only once. I don't think your answer touches that? – Jeppe Stig Nielsen Mar 03 '14 at 06:09
  • @JeppeStigNielsen: The asker said "both class does not dispose", meaning that `Disposed` is not written at all. On the other hand, English is obviously not his first language, so your interpretation *might* be correct as well. – Heinzi Mar 03 '14 at 06:14
3

using statement for reference types is transformed into

{
    ResourceType resource = expression;
    IDisposable d = (IDisposable)resource;
    try {
        statement;
    }
    finally {
        if (d != null) d.Dispose();
    }
}

As you see, initialization is performed before try, so when constructor throws an exception Dispose is not called. That's why you see only one Disposed string printed.

Check 8.13 The using statement in C# specification to see more.

MarcinJuraszek
  • 124,003
  • 15
  • 196
  • 263
1

Is it possible that you did not add a catch statement (as seen in Blorgbeard's answer) but rather just ran your example in Visual Studio?

In that case, Visual Studio will stop execution at the moment the first exception is thrown, so yes, person will not be disposed. This, however, is a "feature" of the development environment and won't affect your program after deployment.

Community
  • 1
  • 1
Heinzi
  • 167,459
  • 57
  • 363
  • 519