tags:

views:

202

answers:

8

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)

+11  A: 

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()
}
munissor
Note that someObject = new SomeObject() places before try block!
Sergey Teplyakov
+5  A: 

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();
}
Henk Holterman
+5  A: 

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.

Sergey Teplyakov
+1  A: 

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.

Findekano
+1  A: 

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.

Gorpik
A: 

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.

cornerback84
+1  A: 

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.

Hans Passant
btw there's no need to do another { } clausule. "Using" can stack. Remove the first { and last } and you will be fine :)
PoweRoy
@PoweRoy: surely this isn't the real code, the OP no doubt actually uses the "someObject" variable somewhere.
Hans Passant
A: 

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.

KMan