Question

Am I right that you'd only need a using() for the outermost stream if you're doing e.g

MemoryStream mstr = new MemoryStream();

using(StreamWriter w = new StreamWriter(mstr)) {
    ....
}

As disposing the StreamWriter should also dispose/close the underlying stream, there's no need to do this ?:

using(MemoryStream mstr = new MemoryStream())
using(StreamWriter w = new StreamWriter(mstr)) {
    ....
}

(Note these are just examples, for how to dispose wrapped streams, not looking for alternatives like just use a StringWriter etc.)

Was it helpful?

Solution

My rule of thumb: If it implements IDisposable, dispose of it.

While currently (and probably forever), calling StreamWriter.Dispose() closes the underlying stream, other stream-derived classes you may use in the future may not. Also, it seems not to actually call Dispose() either, so non-MemoryStreams may not get properly disposed (although I can't think of any that would suffer from that right now).

So, while you can safely dispose only of the StreamWriter, I find it a much better practice to always use using blocks for disposables whenever possible.

OTHER TIPS

It's a good idea to put all dependent resources in their own using blocks from a readability and maintainability point of view as much as anything. e.g. in the below code, after the final brace, it's impossible to attempt to access mstr because it is scoped to within the block where it is valid:

using (MemoryStream mstr = new MemoryStream())
using (StreamWriter w = new StreamWriter(mstr) {
    ....
}

// cannot attempt to access mstr here

If you don't scope it like this, then it's still possible to access mstr outside the scope of where it is valid

MemoryStream mstr = new MemoryStream();
using (StreamWriter w = new StreamWriter(mstr) {
    ....
}

mstr.Write(...); // KABOOM! ObjectDisposedException occurs here!

So while it may not always be necessary (and in this case it isn't) it's a good idea as it both clarifies and enforces your intention as to its scope.

From looking at the StreamWriter.Dispose method in Reflector, it looks like the underlying streams get closed, but not disposed. I would put each stream in a "using" block in order to explicity dispose of them all.

To answer your actual question. TextWriter's Dispose method

public void Dispose()
{
    this.Dispose(true);
    GC.SuppressFinalize(this);
}

It calls a protected Dispose and passes true to it. From TextWriter.Dispose Method (Boolean)

When the disposing parameter is true, this method releases all resources held by any managed objects that this TextWriter references. This method invokes the Dispose method of each referenced object.

However it is best practice to wrap everything that implements IDisposable in a using block, because we cannot guarantee that that the protected Dipose method will always be called with the true parameter.

It's really a better practice to just always use a using block.

"Always", except for the one well-known case of WCF proxy classes, where a design flaw can sometimes cause their Dispose methods to throw an exception, losing your original exception.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top