4

Is it true that the variables declared within a using statement are disposed together because they are in the scope of the using block?

Do I need to do:

using (SomeIdisposableImplementation foo = new SomeIdisposableImplementation()) { using(SomeIdisposableImplementation2 bar = new SomeIdisposableImplementation2()) { } } 

or will this be enough and is "bar" disposed together with "foo"?

using (SomeIdisposableImplementation foo = new SomeIdisposableImplementation()) { SomeIdisposableImplementation2 bar = new SomeIdisposableImplementation2(); } 
1
  • have you missed = in SomeIdisposableImplementation2? Commented Jul 29, 2013 at 15:35

3 Answers 3

11

or will this be enough and is "bar" disposed together with "foo"?

No, bar will not be disposed.

using statement translates into try-finally block, so even if an exception occurs the finally block ensures the call to Dispose method.

Following

using (SomeIdisposableImplementation foo = new SomeIdisposableImplementation()) { SomeIdisposableImplementation2 bar = new SomeIdisposableImplementation2(); } 

Translates into

{ SomeIdisposableImplementation foo; try { foo = new SomeIdisposableImplementation(); SomeIdisposableImplementation2 bar = new SomeIdisposableImplementation2(); } finally { if (foo != null) foo.Dispose(); } } 

Leaving bar un-disposed.

Sign up to request clarification or add additional context in comments.

Comments

4

To get them both disposed with the using statement you do not have to nest them however you can write this

using (SomeIdisposableImplementation foo = new SomeIdisposableImplementation()) { using(SomeIdisposableImplementation2 bar = new SomeIdisposableImplementation2()) { } } 

as

using (SomeIdisposableImplementation foo = new SomeIdisposableImplementation()) using(SomeIdisposableImplementation2 bar = new SomeIdisposableImplementation2()) { } 

Comments

1

In the second version bar will just go out of scope but will not be disposed. But you can put both foo and bar into the same using command:

using (SomeIdisposableImplementation foo = new SomeIdisposableImplementation(), SomeIdisposableImplementation2 bar = new SomeIdisposableImplementation2()) { // use foo and bar } 

you can also just put the variables into the using command:

SomeIdisposableImplementation foo = new SomeIdisposableImplementation(); SomeIdisposableImplementation2 bar = new SomeIdisposableImplementation2(); using (foo, bar) { // use foo and bar } 

9 Comments

The first sentence of this answer is correct. The rest is wrong.
Your edited second option Roland is incorrect. If bar = new SomeIdisposableImplementation2() throws an exception, or a threaded exception occurs before entering the using block foo (and bar) will never be disposed.
The correct syntax is either using(S1 foo = new S1()) using (S2 bar = new S2()) { ... } or, if foo and bar are the same type, using(S1 foo = new S1(), bar = new S1()) { ... }. It would be nice if using(S1 foo = new S1(); S2 bar = new S2()) { ... } were legal, but it is not.
@ChrisSinclair: using is not robust in the face of thread abort exceptions at all. Consider: S1 foo = null; try { foo = new S1(); ... } finally { if (foo != null) foo.Dispose(); }. Now suppose the thread abort exception is thrown during the constructor of S1, but after the constructor has created the unmanaged resource. foo will never be assigned, and so it will still be null in the finally. The only way the resource can be released here is in the finalizer. This is why you need to always write finalizers to be robust in the face of a partially constructed object.
@ChrisSinclair: Right, my point is that though it is correct to note that the code shown here is not robust in the face of a thread abort exception, that is not in of itself a motivation to use the using statement, because the using statement isn't robust against thread aborts either. In general I really care very little about cleaning up resources in the exceptional scenario because it is exceptional. You simply can't clean up resources in all exceptional scenarios, and by definition they are exceptional; worry instead about always cleaning up in typical scenarios.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.