user137348
user137348

Reputation: 10332

What gets disposed when "using" keyword is used

Let's have an example:

using (var someObject = new SomeObject())
{
    var someOtherObject = new SomeOtherObject();
    someOtherObject.someMethod(); 
}

SomeOtherObject also implements IDisposable. Will be SomeOtherObject also disposed when SomeObject get disposed ? What will happen to the SomeOtherObject ? (disposing of SomeOtherObject is not implemented in the Dispose method of SomeObject)

Upvotes: 3

Views: 348

Answers (8)

Kamran Khan
Kamran Khan

Reputation: 9986

Not sure if this is where you are coming from; the someOtherObject is not going to be accessible outside the using block; because of the scoping rules.

using (Stream stream = File.OpenRead(@"c:\test.txt"))
{
   var v1 = "Hello"; //object declared here, wont be accessible outside the block
   stream.Write(ASCIIEncoding.ASCII.GetBytes("This is a test"), 0, 1024);
} //end of scope of stream object; as well as end of scope of v1 object.

v1 = "World!"; //Error, the object is out of scope!

Compiler error: "The name v1 does not exist in the current context."

Even following would throw an error.

    {
        int x=10;
    }

    x = 20; //Compiler error: "The name x does not exist in the current context."

See this and this for more help.

Upvotes: 0

Hans Passant
Hans Passant

Reputation: 941705

You should write it like this:

using (var someObject = new SomeObject()) {
    using (var someOtherObject = new SomeOtherObject()) {
        someOtherObject.someMethod(); 
    }
}

This can get out of hand if your method is creating a lot of disposable objects, common in painting code. Refactor into a helper method or switch to an explicit finally block.

Upvotes: 1

munissor
munissor

Reputation: 3785

No. Only fields in the using clause will be disposed. In your case only someObject.

Basically that code gets translated into

var someObject = null;
try
{
  someObject = new SomeObject()

  var someOtherObject = new SomeOtherObject();
  someOtherObject.someMethod(); 
}
finally
{
  if (someObject != null )
  someObject.Dispose()
}

Upvotes: 11

ata
ata

Reputation: 9011

The Dispose method of object that is referenced by someObject will be called when control leaves the using block. You can SuppressFinalize in Dispose method in which case system will not call that object's finalizer (otherwise it will).
The object that referenced by someOtherObject will, however, be collected by GC at appropriate time, because as the control leave the block, it won't be referenced by any object and will be marked for collection.

Upvotes: 0

Gorpik
Gorpik

Reputation: 11028

someOtherObject will be collected normally by the Garbage Collector. If you did not provide an appropriate finalizer (destructor) that calls Dispose(), this will never get called. Only someObject.Dispose() will be called when execution flow leaves the using block.

Upvotes: 1

Jay Zhu
Jay Zhu

Reputation: 1672

quote from MSDN directly:

As a rule, when you use an IDisposable object, you should declare and instantiate it in a using statement. The using statement calls the Dispose method on the object in the correct way, and (when you use it as shown earlier) it also causes the object itself to go out of scope as soon as Dispose is called. Within the using block, the object is read-only and cannot be modified or reassigned.

Thus only the object declared and instantiated in the using statement will be disposed. For this kind of problem I would suggest you to do some test before post the question.

Upvotes: 1

Sergey Teplyakov
Sergey Teplyakov

Reputation: 11657

No someOtherObject will not disposed.

Your code would traslates in something like this:

var someObject = new SomeObject();
try
{
   var someOtherObject = new SomeOtherObject();
   someOtherObject.someMethod(); 
}
finally
{
    ((IDisposable)someObject).Dispose();
}

So, there are no additional calls to any newly created object would performed.

Upvotes: 5

Henk Holterman
Henk Holterman

Reputation: 273284

No, SomeOtherObject will not be Disposed.

Your code is restructured by the compiler as follows:

var someObject = new SomeObject();
try
{
    var someOtherObject = new SomeOtherObject();
    someOtherObject.someMethod(); 
}
finally
{
    if (someObject != null)
        someObject.Dispose();
}

Upvotes: 5

Related Questions