0

When creating an element that implements IDisposable, Dispose() is called at the end of the using block also if an exception is thrown, if I'm correct.

However, when creating a new element of ClassB within the constructor of a disposable element, will the object of ClassB also be disposed if IDisposable is implemented?

using (ClassA a = new ClassA(new ClassB())) { } 

This may apply to classes that are related to Stream. However, does this apply in general?

2
  • 4
    No. Its is not created within the constructor, but before the constructor. Commented Jun 15, 2016 at 13:17
  • 1
    It would be messed up if it did. You could create a ClassB that implement IDisposable and test with about as many key strokes as this question. Commented Jun 15, 2016 at 13:24

2 Answers 2

5

ClassB would only be disposed if the dispose method of ClassA calls dispose on it.

class ClassA : IDisposable { private ClassB b; public ClassA (ClassB b) { this.b = b; } public void Dispose() { this.b.Dispose(); } } 

If it doesn't you'll need to dispose of it separately:

using (ClassB b = new ClassB()) using (ClassA a = new ClassA(b)) { } 
Sign up to request clarification or add additional context in comments.

9 Comments

Even in the first case an exception in the ClassA constructor would result in leaking the ClassB instance.
So better not trust any class... Is there any way of finding out if a class also disposes of its constructor parameters other than decompiling? Streams seem to do that. But is there a general pattern?
@bytecode77 If it's documented as disposing of the resource, assume it will dispose of it. If it doesn't explicitly state that it does, assume it doesn't.
@bytecode77, it is actually not a good practice to dispose injected objects. The example 1 in this answer is a bad decision. What if a ClassB object is shared among many ClassA instances?
It should be safe to call Dispose multiple times so even if ClassA did dispose of ClassB, if you used the second example it shouldn't cause a problem
|
1

Short answer, no. If ClassB implements IDisposable, you should wrap it in a using block too:

using (var b = new ClassB()) using (var a = new ClassA(b)) { // do stuff } 

Keep in mind that everything you pass to a constructor, or any other method which accepts parameters is evaluated before the constructor or method is invoked.

Some classes, like StreamWriter does with a Stream, will dispose whatever is passed through the constructor, but it's common to leave the disposing to whoever actually instantiated the object.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.